【发布时间】:2016-01-03 12:30:24
【问题描述】:
我的任务是制作自己的 Sobel 方法,而不是使用 OpenCV 中的 cv::Sobel。
我尝试实现我在Programming techniques 找到的一个
但是,当我运行程序时,cv::Mat 会引发错误。有人知道为什么吗?
索贝尔法:
int sobelCorrelation(Mat InputArray, int x, int y, String xory)
{
if (xory == "x") {
return InputArray.at<uchar>(y - 1, x - 1) +
2 * InputArray.at<uchar>(y, x - 1) +
InputArray.at<uchar>(y + 1, x - 1) -
InputArray.at<uchar>(y - 1, x + 1) -
2 * InputArray.at<uchar>(y, x + 1) -
InputArray.at<uchar>(y + 1, x + 1);
}
else if (xory == "y")
{
return InputArray.at<uchar>(y - 1, x - 1) +
2 * InputArray.at<uchar>(y - 1, x) +
InputArray.at<uchar>(y - 1, x + 1) -
InputArray.at<uchar>(y + 1, x - 1) -
2 * InputArray.at<uchar>(y + 1, x) -
InputArray.at<uchar>(y + 1, x + 1);
}
else
{
return 0;
}
}
在另一个函数中调用和处理它:
void imageOutput(Mat image, String path) {
image = imread(path, 0);
Mat dst;
dst = image.clone();
int sum, gx, gy;
if (image.data && !image.empty()){
for (int y = 0; y < image.rows; y++)
for (int x = 0; x < image.cols; x++)
dst.at<uchar>(y, x) = 0.0;
for (int y = 1; y < image.rows - 1; ++y) {
for (int x = 1; x < image.cols - 1; ++x){
gx = sobelCorrelation(image, x, y, "x");
gy = sobelCorrelation(image, x, y, "y");
sum = absVal(gx) + absVal(gy);
if (sum > 255)
sum = 255;
else if (sum < 0)
sum = 0;
dst.at<uchar>(x, y) = sum;
}
}
namedWindow("Original");
imshow("Original", image);
namedWindow("Diagonal Edges");
imshow("Diagonal Edges", dst);
}
waitKey(0);
}
主要:
int main(int argc, char* argv[]) {
Mat image;
imageOutput(image, "C:/Dropbox/2-falling-toast-ted-kinsman.jpg");
return 0;
}
absVal 方法:
int absVal(int v)
{
return v*((v < 0)*(-1) + (v > 0));
}
运行时会抛出这个错误:
Unhandled exception at 0x00007FFC9365A1C8 in Miniproject01.exe: Microsoft C++ exception: cv::Exception at memory location 0x000000A780A4F110.
并指向这里:
template<typename _Tp> inline
_Tp& Mat::at(int i0, int i1)
{
CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
(unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
return ((_Tp*)(data + step.p[0] * i0))[i1];
}
如果有人对我做错了什么有任何建议或想法,将不胜感激!
【问题讨论】:
-
dst.at<uchar>(x, y) = sum;必须改为dst.at<uchar>(y,x) = sum;。但是请注意,您的输出是int,但它会饱和到uchar,因此负值将变为零并且值> 255 将被截断。所以你可能不想做dst = image.clone();但dst = cv::Mat(..., CV_32S)并使用 dst.at访问它 -
是的,我自己发现的。大错特错!非常抱歉。
-
查看更新的评论以获取更多提示可能会出错!
-
我还想指出,这是非常缓慢的实现。你最好写一个卷积循环,并为 sobel X 和 Y 使用两个不同的内核
-
感谢所有伟大的建议!三木,你有卷积循环的代码示例吗?