我正在尝试一些平滑过滤器。我不想使用OpenCV过滤器功能(是的,我知道它存在,但对于教学用途,我想创建我的)。如果您运行我的代码,您将看到输出Mat将被拉伸。我是OpenCV的新手,我无法理解发生了什么。在我的代码中,我将边框添加到原始图片,因此我可以应用过滤器3x3而不会出现stackoverflow问题。
#include <opencv2/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
/*
Smoothing Median
*/
using namespace cv;
using namespace std;
int main()
{
const int sizeFilter = 3;
const int border = 2;
Mat averageFilter(sizeFilter, sizeFilter, CV_8U, 1);
Mat input = imread("lena.jpg");
Mat sizedInput;
sizedInput = input.clone();
int sizeX = input.rows;
int sizeY = input.cols;
namedWindow("sizedInput");
imshow("sizedInput", sizedInput);
// Aggiungo i bordi per filtrare
copyMakeBorder(input, sizedInput, border, border,
border, border, BORDER_REPLICATE);
Mat dst = Mat(sizeX, sizeY, CV_8U);
for (int x = 2; x < sizeX; x++) {
for (int y = 2; y < sizeY; y++) {
int sum = 0;
sum = (int)sizedInput.at<uchar>(x - 1, y - 1)
+ (int)sizedInput.at<uchar>(x - 1, y)
+ (int)sizedInput.at<uchar>(x , y - 1)
+ (int)sizedInput.at<uchar>(x, y)
+ (int)sizedInput.at<uchar>(x, y + 1)
+ (int)sizedInput.at<uchar>(x + 1, y - 1)
+ (int)sizedInput.at<uchar>(x + 1, y + 1);
sum = sum * (0.11);
dst.at<uchar>(x , y) = sum;
}
}
namedWindow("Blu");
imshow("Blu", dst);
waitKey();
return 0;
}
答案 0 :(得分:0)
您的工作就好像图像是灰度(.at<uchar>
),但您将图像作为彩色图像加载。
通过这种方式,您基本上只能读取三分之一的图像像素。彩色图像存储为序列:BGRBGRBGR...
,而灰度图像存储为:XXXXXXXXX...
(X表示灰色)。例如,如果您读取第二个灰度值,则可以有效地读取第一个绿色值:
bytes: 0 1 2 3 4 5 6 7 8 ...
B G R B G R B G R ...
X X X X X X X X X ...
^
生成的图像在水平方向上显示为拉伸3倍。
直接以灰度加载图像:
Mat input = imread("lena.jpg", IMREAD_GRAYSCALE);
或加载后转换:
Mat input = imread("lena.jpg");
cvtColor(input, input, BGR2GRAY).
除此之外,请注意您使用了令人困惑的命名约定。 x 应该引用列, y 引用行。