在 opencv2 C++ 中创建 3x3 sobel 运算符

发布于 2024-12-09 07:43:33 字数 1077 浏览 0 评论 0原文

我试图根据下面代码中三个通道上的 gx 和 gy 矩阵创建我自己的索贝尔边缘检测。
[[0,1,2], [-1,0,1], [-2,-1,0]] 我

[-2,-1,0],
 [-1,0,1],
 [0,1,2]]

在代码中进一步编辑了变量 j 和 i,但它不起作用,我如何在这三个通道上创建索贝尔边缘检测

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

void salt(cv::Mat &image, int n) {

int i,j;
for (int k=0; k<n; k++) {

    // rand() is the MFC random number generator
    i= rand()%image.cols;
    j= rand()%image.rows;


    if (image.channels() == 1) { // gray-level image

        image.at<uchar>(j,i)= 255; 

    } else if (image.channels() == 3) { // color image

        image.at<cv::Vec3b>(j,i)[0]= 255; 
        image.at<cv::Vec3b>(j-1,i-1)[1]= 255; 
        image.at<cv::Vec3b>(j,i-1)[2]= 255; 
    }
}
}

int main()
{
srand(cv::getTickCount()); // init random number generator

cv::Mat image= cv::imread("space.jpg",0);

salt(image,3000);

cv::namedWindow("Image");
cv::imshow("Image",image);

cv::imwrite("salted.bmp",image);

cv::waitKey(5000);

return 0;
}

Im trying to create my own sobel edge detection based off of the gx and gy matrices on three channels i have in my code below.
[[0,1,2],
[-1,0,1],
[-2,-1,0]]
and

[-2,-1,0],
 [-1,0,1],
 [0,1,2]]

I edited the variables j and i in my code further down but it is not working, how can i create a sobel edge detection on those three channels

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

void salt(cv::Mat &image, int n) {

int i,j;
for (int k=0; k<n; k++) {

    // rand() is the MFC random number generator
    i= rand()%image.cols;
    j= rand()%image.rows;


    if (image.channels() == 1) { // gray-level image

        image.at<uchar>(j,i)= 255; 

    } else if (image.channels() == 3) { // color image

        image.at<cv::Vec3b>(j,i)[0]= 255; 
        image.at<cv::Vec3b>(j-1,i-1)[1]= 255; 
        image.at<cv::Vec3b>(j,i-1)[2]= 255; 
    }
}
}

int main()
{
srand(cv::getTickCount()); // init random number generator

cv::Mat image= cv::imread("space.jpg",0);

salt(image,3000);

cv::namedWindow("Image");
cv::imshow("Image",image);

cv::imwrite("salted.bmp",image);

cv::waitKey(5000);

return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枫林﹌晚霞¤ 2024-12-16 07:43:33

我对这个问题有点困惑,因为这个问题与索贝尔滤波器有关,但您提供了一个为图像添加噪声的函数。

首先,这是 Sobel 函数,它将调用经典的 sobel 函数(将计算 dx 和 dy 梯度)。

其次,有更通用的 filter2D ,它可以让您应用任意内核(就像您在问题中创建的内核)。

最后,如果您想在每个通道或波段中应用不同的内核,您可以按照 filter2D 文档的暗示进行操作,对图像调用 split,然后在每个通道上调用 filter2D,然后将这些值组合成单个波段图像使用矩阵运算符。

我认为您可能会问的最复杂的事情是如何找到添加到图像中的盐的位置,答案是为每个带创建一个内核,如下所示:

band 0:

[[ 0, 0, 0],
 [ 0, 1, 0],
 [ 0, 0, 0]]

band 1:

[[ 1, 0, 0],
 [ 0, 0, 0],
 [ 0, 0, 0]]

band 2:

[[ 0, 1, 0],
 [ 0, 0, 0],
 [ 0, 0, 0]]

Be确保将锚点放在内核 (1,1) 的中心。

I'm a little confused by the question, because the question relates to sobel filters, but you provided a function that adds noise to an image.

To start with, here is the Sobel function, which will call the classic sobel functions (that will calculate dx and dy gradients).

Secondly, there is the more generic filter2D which will let you apply an arbitrary kernel (like the one you created in the question).

Lastly, if you want to apply a different kernel in each channel or band, you can do as the filter2D documentation implies, and call split on an image, and then call filter2D on each channel, and then combine the values into a single band image using the matrix operators.

The most complicated thing I think you could be asking is how to find the locations of that salt you added to the image, and the answer would be to make a kernel for each band like so:

band 0:

[[ 0, 0, 0],
 [ 0, 1, 0],
 [ 0, 0, 0]]

band 1:

[[ 1, 0, 0],
 [ 0, 0, 0],
 [ 0, 0, 0]]

band 2:

[[ 0, 1, 0],
 [ 0, 0, 0],
 [ 0, 0, 0]]

Be sure to put the anchor in the center of the kernel (1,1).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文