OpenCV C/C++上的膨胀图像

mv1qrgav  于 2023-02-09  发布在  C/C++
关注(0)|答案(1)|浏览(249)

我想创建一个膨胀图像,使用一个内核,该内核遍历整个图像,并检查内核区域是否为0,如果是,它会给新图像一个像素255。我的代码给我一个全黑的dst,我不知道为什么。这是代码:

Mat vcpi_binary_dilate(Mat src)
{
    if (src.empty())
    {
        cout << "Failed to load image.";
        return src;
    }

    Mat dst(src.rows, src.cols, CV_8UC1, Scalar(0));

    const int kernnel = 3;
    int array[kernnel * kernnel] = {};

    for (int y = kernnel / 2; y < src.cols - kernnel / 2; y++)
    {
        for (int x = kernnel / 2; x < src.rows - kernnel / 2; x++)
            for (int yk = -kernnel / 2; yk <= kernnel / 2; yk++)
            {
                for (int xk = -kernnel / 2; xk <= kernnel / 2; xk++)
                {
                    if (src.at<uchar>(y + yk, x + xk) == 0)
                    {
                        dst.at<uchar>(y + yk, x + xk) = 255;
                    }
                }
            }
    }

    imshow("Image ", src);
    imshow("Image dilate", dst);
    waitKey(0);

    return dst;
}

我希望有一个这种类型的输出图像。

cbeh67ev

cbeh67ev1#

我不太清楚你要实现的算法。
但有一件事是绝对错误的:
图像的尺寸混淆了-
cols是宽度,对应于x轴。
rows是高度,对应于y轴。
这会导致您使用坐标无效的cv::Mat::at访问图像。

    • 因此,您需要更改:**
for (int y = kernnel / 2; y < src.cols - kernnel / 2; y++)
{
    for (int x = kernnel / 2; x < src.rows - kernnel / 2; x++)
    {
    • 收件人:**
//--------------------------------vvvv--------------------
for (int y = kernnel / 2; y < src.rows - kernnel / 2; y++)
{
//------------------------------------vvvv--------------------
    for (int x = kernnel / 2; x < src.cols - kernnel / 2; x++)
    {

注意,这与您调用...at<uchar>(y + yk, x + xk)是一致的,因为cv::Mat::at首先需要row(即y坐标)。

在看过你的评论中的matlab代码后,它应用了一个与你在问题中描述的不同的算法,你需要做以下修改:
1.调用与matlab的im2bw等价的函数。
1.更新dst当前像素,而不是邻域中的像素。
可能是这样的:

cv::Mat vcpi_binary_dilate(cv::Mat src) {

    if (src.empty()) {
        std::cout << "Failed to load image.";
        return src;
    }

    cv::threshold(src, src, 127, 255, CV_THRESH_BINARY);

    cv::Mat dst(src.rows, src.cols, CV_8UC1, cv::Scalar(255));  // <-- Replacement for im2bw, might need tuning.

    const int kernnel = 3;
    int array[kernnel * kernnel] = {};

    for (int y = kernnel / 2; y < src.rows - kernnel / 2; y++)
    {
        for (int x = kernnel / 2; x < src.cols - kernnel / 2; x++)
        {
            for (int yk = -kernnel / 2; yk <= kernnel / 2; yk++)
            {
                for (int xk = -kernnel / 2; xk <= kernnel / 2; xk++)
                {
                    if (src.at<uchar>(y + yk, x + xk) == 0) {
                        dst.at<uchar>(y, x) = 0;   // <-- Update the current pixel, not the one in the neighborhood.
                    }
                }
            }
        }
    }

    cv::imshow("Image ", src);
    cv::imshow("Image dilate", dst);
    cv::waitKey(0);
    return dst;
}

相关问题