To smooth the image, a Gaussian filter kernel is convolved with the image.
高斯滤波的实质就是用高斯核对图片进行卷积操作
算法较为简单,在复杂度运行效率方面还有很多需要改进的
从RGB色转为灰度色算法(转) - carekee - 博客园 (cnblogs.com)
Mat gray(Mat& image) {
Mat dst = Mat::zeros(image.size(), CV_8UC1);
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++)
{
dst.at(i, j) = 0.114*image.at(i, j)[0] + 0.587*image.at(i, j)[1] + 0.299*image.at(i, j)[2];
//将彩色图像的三个通道的值,每个乘以对应的比例,进行相加,opencv B G R
}
}
return dst;
}
padding 的选择,5乘5(padding = 2),3乘3(padding = 1)
如上图,要是右上角的小正方形位于卷积核的中心正方形处,就需要填充一层空的矩形
因此可以推至5乘5的卷积核
我选用的是3*3 的卷积,故填充为1
Mat Padding(Mat& image,int padNum = 1) {
Mat dst = Mat::zeros(image.size[0]+2*padNum, image.size[1] + 2*padNum, CV_8UC1);
cout << "dst size" << dst.size << endl;
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++)
{
dst.at(i + 1, j + 1) = image.at(i, j);
}
}
return dst;
}
同样 3*3 的卷积核在主函数里
Mat convolution(Mat &image, Mat &kernal) {
Mat dst = Mat ::zeros(image.size(),image.type());
// padding 填充
Mat test = Padding(image);// 6*6 填充一层 变 8*8
//cout << "conv test" << endl;
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++)
{
double pixSum = 0;
//这个像素就在卷积核的中心处
for (int k = 0; k < kernal.rows; k++) {
for (int l = 0; l < kernal.cols; l++) {
//cout << kernal.at(k, l) << endl;
//cout << double(test.at(k + i, l + j)) << endl;
pixSum += kernal.at(k, l) * double(test.at(k + i, l + j));
}
}
dst.at(i, j) = uchar(pixSum);
}
}
return dst;
}
因为使用的是3X3 的卷积核,所以模糊的不明显
#include
#include
using namespace cv;
using namespace std;
Mat gray(Mat& image) {
Mat dst = Mat::zeros(image.size(), CV_8UC1);
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++)
{
dst.at(i, j) = 0.114*image.at(i, j)[0] + 0.587*image.at(i, j)[1] + 0.299*image.at(i, j)[2];
//将彩色图像的三个通道的值,每个乘以对应的比例,进行相加,opencv B G R
}
}
return dst;
}
Mat Padding(Mat& image,int padNum = 1) {
Mat dst = Mat::zeros(image.size[0]+2*padNum, image.size[1] + 2*padNum, CV_8UC1);
cout << "dst size" << dst.size << endl;
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++)
{
dst.at(i + 1, j + 1) = image.at(i, j);
}
}
return dst;
}
Mat convolution(Mat &image, Mat &kernal) {
Mat dst = Mat ::zeros(image.size(),image.type());
// padding 填充
Mat test = Padding(image);// 6*6 填充一层 变 8*8
//cout << "conv test" << endl;
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++)
{
double pixSum = 0;
//这个像素就在卷积核的中心处
for (int k = 0; k < kernal.rows; k++) {
for (int l = 0; l < kernal.cols; l++) {
//cout << kernal.at(k, l) << endl;
//cout << double(test.at(k + i, l + j)) << endl;
pixSum += kernal.at(k, l) * double(test.at(k + i, l + j));
}
}
dst.at(i, j) = uchar(pixSum);
}
}
return dst;
}
/*
Mat GaussianBlur(Mat& image){
//实质就是用高斯核实现一个卷积操作
}
*/
int main(int argc, char* argv[])
{
//load pics
string imgPath = "E:\\研究生\\数字图像处理\\c++\\字符识别\\Project1\\beauty.jpg";
Mat srcImg = imread(imgPath);//RGB,JPG,PNG,TIFF格式
if (srcImg.empty()) {
cout << "can't load pic" << endl;
exit(-1);
}
//show pics
//imshow("air plane",srcImg);
//转灰度化
Mat image_gray = gray(srcImg);
imshow("gray img", image_gray);
//3*3 的卷积核 , padding = 1
Mat kernal = (Mat_(3, 3) << 1, 2, 1,2, 4, 2,1,2, 1);
kernal = kernal / 16;
//卷积实现高斯滤波
Mat imgconv = convolution(image_gray, kernal);
imshow("img conv", imgconv);
waitKey(0);//wait function
return 0;
}
模糊效果好像差不多
int main(int argc, char* argv[])
{
//load pics
string imgPath = "E:\\研究生\\数字图像处理\\c++\\字符识别\\Project1\\beauty.jpg";
Mat srcImg = imread(imgPath,0);//RGB,JPG,PNG,TIFF格式
if (srcImg.empty()) {
cout << "can't load pic" << endl;
exit(-1);
}
//show pics
imshow("src",srcImg);
Mat dst;
GaussianBlur(srcImg,dst,Size(3,3),0,0);
imshow("opencv gsblur", dst);
waitKey(0);//wait function
return 0;
}