OpenCV Prewitt从头开始怪异

时间:2015-12-30 13:14:40

标签: c++ opencv image-processing

因为这是一个图像处理类的项目,我必须从头开始实现几个线性过滤器(我不应该使用已经实现的OpenCV功能,如Sobel,甚至不是2D过滤器功能) 。代码就在问题的最后。

由于使用Sobel算子处理的图像与Prewitt的图像具有相似的结果,因此我用一个窗口作为测试窗口,我在其中显示Sobel处理的图像。 我只是在水平方向上应用了一个算子,但我已经得到了奇怪的结果。图像不言自明:

原始图片: Original image

我在水平方向上使用Prewitt算子的结果: My processed image

我得到一个奇怪的蓝米色图案而不是黑白水平线。发生了什么事?

以下是代码:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
using namespace std;
int main(int, char** argv)
{


    int Hprewitt[3][3] = { { -1, 0, 1 }, { -1, 0, 1 }, { -1, 0, 1 } };
    int Vprewitt[3][3] = { { -1, -1, -1 }, { 0, 0, 0 }, { 1, 1, 1 } };
    int tempInput[3][3];
    int tempPixel=0;

    Mat src, src_gray;
    Mat grad;
    const char* window_name = "Sobel Edge Detector";
    const char* window_name2 = "Prewitt";
    int scale = 1;
    int delta = 0;
    int ddepth = CV_16S;
    int computedIntensity;
    src = imread(argv[1]);
    if (src.empty())
    {
        return -1;
    }

        namedWindow(window_name2, WINDOW_AUTOSIZE);
        Mat HprewittMat(src.rows, src.cols, CV_8UC3, Scalar(0, 0, 0));
        GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT);
        cvtColor(src, src_gray, COLOR_RGB2GRAY);
        namedWindow(window_name, WINDOW_AUTOSIZE);
        Scalar intensity = src.at<uchar>(Point(50, 50)); // this is how to access intensity at a certain pixel
        Vec3b scalarTempPixel = src.at<Vec3b>(Point(1, 1));

        cout << "Pixel (50,50) has intensity: " << intensity.val[0] << endl;


        // applying horizontal prewitt operator
        cout << "\n Image has resolution: " << src.cols << "x" << src.rows << "\n";

            for (int i = 2; i < src.cols-1; i++){ // currently going from column 2 to n-2, same for row
                for (int j = 2; j < src.rows-1; j++){
        // storing a temporary 3x3 input matrix centered on the current pixel
                //  cout << "Matrix centered on pixel: [" << i << "," << j << "] \n";
                    for (int k = -1; k < 2; k++){
                        for (int l = -1; l < 2; l++){
                            intensity = src.at<uchar>(Point(i + k, j + l));
                            tempInput[k+1][l+1] = intensity.val[0];
                        //  cout << "[" << intensity.val[0] << "]";
                        }
                //      cout << " \n";
                    }
// convolution of horizontal prewitt kernel with current 3x3 matrix
                    for (int x = 0; x < 3; x++){
                        for (int y = 0; y < 3; y++){
                            tempPixel = tempPixel + tempInput[x][y] * Hprewitt[x][y];
                        }
                    }

                    scalarTempPixel[0] = tempPixel;
                    HprewittMat.at<Vec3b>(Point(i, j)) = scalarTempPixel;
                }
            }


        Mat grad_x, grad_y;
        Mat abs_grad_x, abs_grad_y;
        Sobel(src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);
        convertScaleAbs(grad_x, abs_grad_x);
        Sobel(src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT);
        convertScaleAbs(grad_y, abs_grad_y);
        addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
        imshow(window_name, grad);
        imshow(window_name2, HprewittMat);

        waitKey(0);
        return 0;
    }

所以在这一点上我做了以下事情: 我在&#34; src&#34;中读取图像,然后我创建了HprewittMat,我用原始图像的行数和列数初始化它,但是用黑色像素。然后我将src图像转换为灰色图像。然后我遍历原始图像的每个像素,并且对于每个像素,我使用周围像素和水平prewitt内核进行卷积掩模。然后我将该值存储在&#34; tempPixel&#34;并把它放在HprewittMat图像中。 下一步是使用垂直内核执行相同的操作,然后计算渐变内核。

我问这个问题是因为我发现了关于如何操纵单个像素的类似问题,但通常用于python或java。这也可能是我使用的逻辑中的一些缺陷。

0 个答案:

没有答案