gpt4 book ai didi

c++ - OpenCV 中的 Sobel 导数

转载 作者:太空宇宙 更新时间:2023-11-03 22:28:34 26 4
gpt4 key购买 nike

我的任务是制作自己的 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];
}

如果有人对我做错了什么有任何建议或想法,我们将不胜感激!

最佳答案

此代码片段用于演示如何计算 Sobel 3x3 导数,将图像与 Sobel 内核进行卷积。您可以轻松地扩展到不同的内核大小,将内核半径作为 my_sobel 的输入,并创建适当的内核。

#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;


void my_sobel(const Mat1b& src, Mat1s& dst, int direction)
{
Mat1s kernel;
int radius = 0;

// Create the kernel
if (direction == 0)
{
// Sobel 3x3 X kernel
kernel = (Mat1s(3,3) << -1, 0, +1, -2, 0, +2, -1, 0, +1);
radius = 1;
}
else
{
// Sobel 3x3 Y kernel
kernel = (Mat1s(3, 3) << -1, -2, -1, 0, 0, 0, +1, +2, +1);
radius = 1;
}

// Handle border issues
Mat1b _src;
copyMakeBorder(src, _src, radius, radius, radius, radius, BORDER_REFLECT101);

// Create output matrix
dst.create(src.rows, src.cols);

// Convolution loop

// Iterate on image
for (int r = radius; r < _src.rows - radius; ++r)
{
for (int c = radius; c < _src.cols - radius; ++c)
{
short s = 0;

// Iterate on kernel
for (int i = -radius; i <= radius; ++i)
{
for (int j = -radius; j <= radius; ++j)
{
s += _src(r + i, c + j) * kernel(i + radius, j + radius);
}
}
dst(r - radius, c - radius) = s;
}
}
}

int main(void)
{
Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

// Compute custom Sobel 3x3 derivatives
Mat1s sx, sy;
my_sobel(img, sx, 0);
my_sobel(img, sy, 1);

// Edges L1 norm
Mat1b edges_L1;
absdiff(sx, sy, edges_L1);


// Check results against OpenCV
Mat1s cvsx,cvsy;
Sobel(img, cvsx, CV_16S, 1, 0);
Sobel(img, cvsy, CV_16S, 0, 1);
Mat1b cvedges_L1;
absdiff(cvsx, cvsy, cvedges_L1);

Mat diff_L1;
absdiff(edges_L1, cvedges_L1, diff_L1);

cout << "Number of different pixels: " << countNonZero(diff_L1) << endl;

return 0;
}

关于c++ - OpenCV 中的 Sobel 导数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32972513/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com