首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >拉普拉斯锐化效果有点灰暗C++

拉普拉斯锐化效果有点灰暗C++
EN

Stack Overflow用户
提问于 2018-10-10 15:43:42
回答 2查看 884关注 0票数 0

我试图实现拉普拉斯过滤器锐化图像。但结果有点灰色,我不知道我的代码出了什么问题。

到目前为止我的工作是

代码语言:javascript
运行
复制
     img = imread("moon.png", 0);
     Mat convoSharp() {

    //creating new image
    Mat res = img.clone();
    for (int y = 0; y < res.rows; y++) {
        for (int x = 0; x < res.cols; x++) {
            res.at<uchar>(y, x) = 0.0;
        }
    }

    //variable declaration
    //change -5 to -4 for original result.
    int filter[3][3] = { {0,1,0},{1,-4,1},{0,1,0} };
    //int filter[3][3] = { {-1,-2,-1},{0,0,0},{1,2,1} };
    int height = img.rows;
    int width = img.cols;
    int **temp = new int*[height];
    for (int i = 0; i < height; i++) {
        temp[i] = new int[width];
    }
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            temp[i][j] = 0;
        }
    }
    int filterHeight = 3;
    int filterWidth = 3;
    int newImageHeight = height - filterHeight + 1;
    int newImageWidth = width - filterWidth + 1;
    int i, j, h, w;

    //convolution
    for (i = 0; i < newImageHeight; i++) {
        for (j = 0; j < newImageWidth; j++) {
            for (h = i; h < i + filterHeight; h++) {
                for (w = j; w < j + filterWidth; w++) {
                    temp[i][j] += filter[h - i][w - j] * (int)img.at<uchar>(h, w);
                }
            }
        }
    }

    //find max and min
    int max = 0;
    int min = 100;
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            if (temp[i][j] > max) {
                max = temp[i][j];
            }
            if (temp[i][j] < min) {
                min = temp[i][j];
            }
        }
    }

    //clamp 0 - 255
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            res.at<uchar>(i, j) = 0 + (temp[i][j] - min)*(255 - 0) / (max - min);
        }
    }

    //empty the temp array
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            temp[i][j] = 0;
        }
    }

    //img - res and store it in temp array
    for (int y = 0; y < res.rows; y++) {
        for (int x = 0; x < res.cols; x++) {
            //int a = (int)img.at<uchar>(y, x) - (int)res.at<uchar>(y, x);
            //cout << a << endl;
            temp[y][x] = (int)img.at<uchar>(y, x) - (int)res.at<uchar>(y, x);

        }
    }

    //find the new max and min
    max = 0;
    min = 100;
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            if (temp[i][j] > max) {
                max = temp[i][j];
            }
            if (temp[i][j] < min) {
                min = temp[i][j];
            }
        }
    }

    //clamp it back to 0-255
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            res.at<uchar>(i, j) = 0 + (temp[i][j] - min)*(255 - 0) / (max - min);
            temp[i][j] = (int)res.at<uchar>(i, j);
        }
    }



    return res;
}

这是结果

正如您在上面的代码中所看到的,我已经将像素值标准化为0-255。我还是不知道这里出了什么问题。这里有人能解释一下为什么吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-10 16:32:29

灰色是因为,as Max suggested in his answer,您正在缩放到0-255范围,而不是夹紧(正如您在代码中的注释所暗示的)。

但是,这并不是代码中的所有问题。Laplace运算符的输出包含负值。您可以很好地将这些存储在int中。但是,然后您缩放并复制到一个char。别干那事!

您需要将Laplace的结果不变地添加到您的图像中。这样,你的图像中的一些像素会变得更暗,一些更轻。这就是导致边缘看起来更清晰的原因。

只需跳过代码中的一些循环,并保留一个执行temp = img - temp的循环。这个结果可以自由缩放或夹紧到输出范围,并转换为char

若要夹紧,只需将任何像素值设置在0至0以下,以及任何高于255至255的像素值。不要像你那样计算最小/最大值和比例,因为在那里你会减少对比度,在你的图像上造成灰色的清洗。

您最近的问题非常相似(尽管代码中的问题不同),请再次阅读my answer there,它提出了一种进一步简化代码从而使img-Laplace成为单一卷积的方法。

票数 0
EN

Stack Overflow用户

发布于 2018-10-10 16:21:09

问题是,您正在夹紧和重新缩放图像。看看月亮的左下角:在非常暗的像素旁边有非常亮的像素,然后除了明亮的像素,还有一些灰色的像素。你的锐化过滤器将真正尖峰在明亮的边界,并增加最大。同样,黑色像素将进一步减少。

然后确定最小值和最大值,然后重新绘制整个图像。这必然意味着当显示在上一个灰度中时,整个图像将失去对比度,因为您的过滤器输出的像素值在255以上和0以下。

在输出图像中,仔细观察月亮的边界:

有一个黑色光环(新0)和一个明亮,尖锐的边缘(新的255)。(浏览器图像缩放使其在这个屏幕截图中变得不那么清晰,看看您的原始输出)。其他的一切都被重新定标压碎了,所以以前的黑色(0)现在是深灰色的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52744067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档