自己的平滑过滤器不起作用
own smoothing filter doesn't work
我正在尝试一些平滑过滤器。我不想使用 OpenCV 过滤器功能(是的,我知道它存在,但为了教学用途我想创建我的)。如果你 运行 我的代码,你会看到输出 Mat 会被拉伸。我是 OpenCV 的新手,我无法理解发生了什么。在我的代码中,我为原始图片添加了边框,因此我可以应用 3x3 滤镜而不会出现 Whosebug 问题。
#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;
}
您将图像视为灰度图像 (.at<uchar>
),但您将图像加载为彩色图像。
这样你基本上只读取了图像像素的三分之一。彩色图像存储为序列:BGRBGRBGR...
,而灰度图像为:XXXXXXXXX...
(X 代表灰色)。例如,如果您读取第二个 grayscale 值,您实际上是在读取第一个 green 值:
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 应参考 行 ].
我正在尝试一些平滑过滤器。我不想使用 OpenCV 过滤器功能(是的,我知道它存在,但为了教学用途我想创建我的)。如果你 运行 我的代码,你会看到输出 Mat 会被拉伸。我是 OpenCV 的新手,我无法理解发生了什么。在我的代码中,我为原始图片添加了边框,因此我可以应用 3x3 滤镜而不会出现 Whosebug 问题。
#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;
}
您将图像视为灰度图像 (.at<uchar>
),但您将图像加载为彩色图像。
这样你基本上只读取了图像像素的三分之一。彩色图像存储为序列:BGRBGRBGR...
,而灰度图像为:XXXXXXXXX...
(X 代表灰色)。例如,如果您读取第二个 grayscale 值,您实际上是在读取第一个 green 值:
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 应参考 行 ].