因为这是一个图像处理类的项目,我必须从头开始实现几个线性过滤器(我不应该使用已经实现的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。这也可能是我使用的逻辑中的一些缺陷。