使用OpenCV的平均过滤器
Average Filter with OpenCV
我正在尝试实现一个具有 5x5 内核的平均过滤器,尽管 OpenCV 中有一个函数,但我需要在没有它的情况下做到这一点。有问题,我认为这是变量 uchar,但我尝试了 int、float 和 double,结果图像不正确。我使用填充为 7 的图像。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include "filter.h"
#include <iostream>
#include <fstream>
using namespace std;
using namespace cv;
cv::Mat filter::mean_filter(cv::Mat& image_in){
int centro = 7;
float total = 0.0;
double window[25];
double mean= 0.0;
int final=0;
int nlines, ncols;
cv::Mat kernel = cv::Mat::ones(5, 5, CV_32S);
nlines=image_in.size().height;
ncols=image_in.size().width;
cv::Mat image_out = cv::Mat::zeros(nlines,ncols,CV_32S);
for (unsigned int j=centro; j<nlines - centro; j++){
for (unsigned int z=centro; z<ncols - centro; z++){
window[0]=image_in.at<uchar>(j-2,z-2);
window[1]=image_in.at<uchar>(j-1,z-2);
window[2]=image_in.at<uchar>(j ,z-2);
window[3]=image_in.at<uchar>(j+1,z-2);
window[4]=image_in.at<uchar>(j+2,z-2);
window[5]=image_in.at<uchar>(j-2,z-1);
window[6]=image_in.at<uchar>(j-1,z-1);
window[7]=image_in.at<uchar>(j ,z-1);
window[8]=image_in.at<uchar>(j+1,z-1);
window[9]=image_in.at<uchar>(j+2,z-1);
window[10]=image_in.at<uchar>(j-2,z);
window[11]=image_in.at<uchar>(j-1,z);
window[12]=image_in.at<uchar>(j ,z);
window[13]=image_in.at<uchar>(j+1,z);
window[14]=image_in.at<uchar>(j+2,z);
window[15]=image_in.at<uchar>(j-2,z+2);
window[16]=image_in.at<uchar>(j-1,z+2);
window[17]=image_in.at<uchar>(j ,z+2);
window[18]=image_in.at<uchar>(j+1,z+2);
window[19]=image_in.at<uchar>(j+2,z+2);
window[20]=image_in.at<uchar>(j-2,z+1);
window[21]=image_in.at<uchar>(j-1,z+1);
window[22]=image_in.at<uchar>(j ,z+1);
window[23]=image_in.at<uchar>(j+1,z+1);
window[24]=image_in.at<uchar>(j+2,z+1);
mean=0.0;
final=0;
for (unsigned int k=0; k<25; k++){
mean+=window[k];
}
mean=mean/25;
final=round(mean);
image_out.at<int>(j,z)=final;
}
}
return image_out;
}
我稍微更改了您的代码并有一个有效的解决方案。这是一种非常原始的方法,但它有效。
可能的改进可能是通过跟踪哪些像素离开内核区域以及哪些像素进入内核区域来重用一些已经累积的像素值。另一种改进的可能性是在图像上并行化循环。
cv::Mat mean_filter(cv::Mat& image_in, int kernel)
{
// Make sure you get a grayscale image.
assert(image_in.type() == CV_8UC1);
// Make sure your kernel is an uneven number
assert(kernel % 2 == 1);
// Make sure your kernel is bigger than 1
assert(kernel >= 1);
// for padding calculate the border needed
int padding = (kernel - 1) / 2;
int mean = 0.0;
int final = 0;
int nlines, ncols;
cv::Mat img_temp;
nlines = image_in.size().height;
ncols = image_in.size().width;
// Make propper padding. Here it is done with 0. Padding describes the adding of a border to the image in order to avoid a cropping by applying a filter-mask.
copyMakeBorder(image_in, img_temp, padding, padding, padding, padding, BORDER_CONSTANT, 0);
// allocate the output image as grayscale as the input is grayscale as well
cv::Mat image_out = cv::Mat::zeros(nlines, ncols, CV_8UC1);
// loop over whole image
for (unsigned int j = padding; j<nlines + padding; j++){
for (unsigned int z = padding; z<ncols + padding; z++){
mean = 0.0;
// loop over kernel area
for (int x = -padding; x <= padding; x++){
for (int y = -padding; y <= padding; y++){
// accumulate all pixel-values
mean += img_temp.at<uchar>(j + x, z + y);
}
}
mean = mean / (kernel * kernel);
final = round(mean);
// cast result to uchar and set pixel in output image
image_out.at<uchar>(j - padding, z - padding) = (uchar)final;
}
}
return image_out;
}
相关文章:
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- 带过滤器的现代迭代c++集合
- OpenCV C++.快速计算混淆矩阵
- 在C++代码中包含opencv时,使用ctypes创建.so文件
- C OPENCV中的错误是我的第一个代码(中值过滤器)
- 未定义的参考,差异使用 CUDA 的 OpenCV 中的双边过滤器
- 使用OpenCV的平均过滤器
- OpenCV:如何对通过calcOpticalFlowFarneback获得的载体应用过滤器
- OpenCv 3.3 Cuda 中值过滤器生成 2/3 的图像黑色
- 多维垫子上的opencv过滤器
- OpenCV过滤器C++中的2D负值
- OpenCV Sobel过滤器导致几乎完全黑色的图像
- OpenCV将我自己的过滤器应用于彩色图像
- 对于大于 3 x 3 的尺寸,OpenCV 的 Sobel 过滤器的核系数是多少?
- 如何在opencv中对一个图像应用多个过滤器