4.2.1 图像掩码操作
filter2D函数:计算图像卷积
1 ////////https://blog.csdn.net/qq_34784753/article/details/60144935 2 #include "stdafx.h" 3 4 #include <iostream> 5 #include <opencv2corecore.hpp> 6 #include <opencv2highguihighgui.hpp> 7 #include <opencv2imgprocimgproc.hpp> 8 9 using namespace std; 10 using namespace cv; 11 12 Mat Myfilter2D(Mat srcImage); 13 Mat filter2D_(Mat srcImage); 14 15 int main() 16 { 17 Mat srcImage = imread("D:\大海.jpg"); 18 if (!srcImage.data) 19 { 20 cout << "读入图片失败" << endl; 21 return -1; 22 } 23 Mat srcGray; 24 cvtColor(srcImage, srcGray, CV_BGR2GRAY); 25 imshow("srcGray", srcGray); 26 Mat resultImage = Myfilter2D(srcGray); 27 imshow("resultImage1", resultImage); 28 resultImage = filter2D_(srcGray); 29 imshow("resultImage2", resultImage); 30 waitKey(); 31 return 0; 32 } 33 34 //基于像素邻域的掩码操作 35 Mat Myfilter2D(Mat srcImage) 36 { 37 const int nChannels = srcImage.channels(); 38 Mat resultImage(srcImage.size(), srcImage.type()); 39 for (int j = 1; j < srcImage.rows - 1; j++) 40 { 41 //获取邻域指针 42 const uchar* previous = srcImage.ptr<uchar>(j - 1); 43 const uchar* current = srcImage.ptr<uchar>(j); 44 const uchar* next = srcImage.ptr<uchar>(j + 1); 45 uchar * output = resultImage.ptr<uchar>(j); 46 for (int i = nChannels; i < nChannels*(srcImage.cols - 1); ++i) 47 { 48 //进行4-邻域掩码操作 49 *output++ = saturate_cast<uchar>(current[i - nChannels] + current[i + nChannels] 50 + previous[i] + next[i]) / 4; 51 } 52 } 53 54 //进行边界处理 55 resultImage.row(0).setTo(Scalar(0)); 56 resultImage.row(resultImage.rows - 1).setTo(Scalar(0)); 57 resultImage.col(0).setTo(Scalar(0)); 58 resultImage.col(resultImage.cols - 1).setTo(Scalar(0)); 59 return resultImage; 60 } 61 62 //使用自带掩码库进行操作 63 Mat filter2D_(Mat srcImage) 64 { 65 Mat resultImage(srcImage.size(), srcImage.type()); 66 //构造核函数因子 67 Mat kern = (Mat_<float>(3, 3) << 0, 1, 0, 68 1, 0, 1, 69 0, 1, 0) / (float)(4); 70 filter2D(srcImage, resultImage, srcImage.depth(), kern); 71 return resultImage; 72 }
4.2.2 离散傅里叶
1 ///////https://blog.csdn.net/keith_bb/article/details/53389819 2 #include <iostream> 3 #include <opencv2/core.hpp> 4 #include <opencv2/highgui.hpp> 5 #include <opencv2/imgproc.hpp> 6 7 using namespace std; 8 using namespace cv; 9 10 int main() 11 { 12 Mat I = imread("D:\lena.jpg", IMREAD_GRAYSCALE); //读入图像灰度图 13 14 //判断图像是否加载成功 15 if (I.empty()) 16 { 17 cout << "图像加载失败!" << endl; 18 return -1; 19 } 20 else 21 cout << "图像加载成功!" << endl << endl; 22 23 Mat padded; //以0填充输入图像矩阵 24 int m = getOptimalDFTSize(I.rows); 25 int n = getOptimalDFTSize(I.cols); 26 27 //填充输入图像I,输入矩阵为padded,上方和左方不做填充处理 28 copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0)); 29 30 Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(),CV_32F) }; 31 Mat complexI; 32 merge(planes, 2, complexI); //将planes融合合并成一个多通道数组complexI 33 34 dft(complexI, complexI); //进行傅里叶变换 35 36 //计算幅值,转换到对数尺度(logarithmic scale) 37 //=> log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2)) 38 split(complexI, planes); //planes[0] = Re(DFT(I),planes[1] = Im(DFT(I)) 39 //即planes[0]为实部,planes[1]为虚部 40 magnitude(planes[0], planes[1], planes[0]); //planes[0] = magnitude 41 Mat magI = planes[0]; 42 43 magI += Scalar::all(1); 44 log(magI, magI); //转换到对数尺度(logarithmic scale) 45 46 //如果有奇数行或列,则对频谱进行裁剪 47 magI = magI(Rect(0, 0, magI.cols&-2, magI.rows&-2)); 48 49 //重新排列傅里叶图像中的象限,使得原点位于图像中心 50 int cx = magI.cols / 2; 51 int cy = magI.rows / 2; 52 53 Mat q0(magI, Rect(0, 0, cx, cy)); //左上角图像划定ROI区域 54 Mat q1(magI, Rect(cx, 0, cx, cy)); //右上角图像 55 Mat q2(magI, Rect(0, cy, cx, cy)); //左下角图像 56 Mat q3(magI, Rect(cx, cy, cx, cy)); //右下角图像 57 58 //变换左上角和右下角象限 59 Mat tmp; 60 q0.copyTo(tmp); 61 q3.copyTo(q0); 62 tmp.copyTo(q3); 63 64 //变换右上角和左下角象限 65 q1.copyTo(tmp); 66 q2.copyTo(q1); 67 tmp.copyTo(q2); 68 69 //归一化处理,用0-1之间的浮点数将矩阵变换为可视的图像格式 70 normalize(magI, magI, 0, 1, CV_MINMAX); 71 72 imshow("输入图像", I); 73 imshow("频谱图", magI); 74 waitKey(0); 75 76 77 return 0; 78 }
4.2.3 图像卷积
1 ////////https://blog.csdn.net/keith_bb/article/details/53103026 2 #include <iostream> 3 #include <opencv2/core.hpp> 4 #include <opencv2/highgui.hpp> 5 #include <opencv2/imgproc.hpp> 6 7 using namespace std; 8 using namespace cv; 9 10 int main() 11 { 12 Mat srcImage = imread("D:\彩色lena.jpg"); 13 14 //判断图像是否加载成功 15 if (srcImage.data) 16 cout << "图像加载成功!" << endl << endl; 17 else 18 { 19 cout << "图像加载失败!" << endl << endl; 20 return -1; 21 } 22 namedWindow("srcImage", WINDOW_AUTOSIZE); 23 imshow("srcImage", srcImage); 24 25 Mat kern = (Mat_<char>(3, 3) << 0, -1, 0, 26 -1, 5, -1, 27 0, -1, 0); 28 Mat dstImage; 29 filter2D(srcImage, dstImage, srcImage.depth(), kern); 30 namedWindow("dstImage", WINDOW_AUTOSIZE); 31 imshow("dstImage", dstImage); 32 33 34 waitKey(0); 35 36 return 0; 37 }
拓展:
https://blog.csdn.net/qq_32864683/article/details/79748027
https://blog.csdn.net/chaipp0607/article/details/72236892?locationNum=9&fps=1