OpenCV4学习(14-27)

发布时间:2026/7/13 15:42:51

OpenCV4学习(14-27) 目录14.LUT查找表LUT()15.图像尺寸变换resize()flip()hconcat()vconcat()16.图像仿射变换warpAffine()getRotationMatrix2D()getAffineTransform()17.图像透视变换getPerspectiveTransform()warpPerspective()18.图像中绘制基础图形line()circle()ellipse()rectangle()fillPoly()putText()19.ROI区域截取Range()copyTo()20.高斯图像金字塔pyrDown()21.拉普拉斯图像金字塔.pyrUp()22.创建滑动条createTrackbar()23.鼠标事件响应setMouseCallBack()MouseCallback()24.图像直方图绘制calcHist()25.直方图均衡化equalizeHist()26.直方图匹配27.模板匹配matchTemplate()14.LUT查找表LUT()#include opencv2\opencv.hpp #include iostream using namespace std; using namespace cv; int main(int agrc, char** agrv) { //LUT查找表第一层 uchar lutFirst[256]; for (int i 0; i256; i) { if (i 100) lutFirst[i] 0; if (i 100 i 200) lutFirst[i] 100; if (i 200) lutFirst[i] 255; } Mat lutOne(1, 256, CV_8UC1, lutFirst); //LUT查找表第二层 uchar lutSecond[256]; for (int i 0; i256; i) { if (i 100) lutSecond[i] 0; if (i 100 i 150) lutSecond[i] 100; if (i 150 i 200) lutSecond[i] 150; if (i 200) lutSecond[i] 255; } Mat lutTwo(1, 256, CV_8UC1, lutSecond); //LUT查找表第三层 uchar lutThird[256]; for (int i 0; i256; i) { if (i 100) lutThird[i] 100; if (i 100 i 200) lutThird[i] 200; if (i 200) lutThird[i] 255; } Mat lutThree(1, 256, CV_8UC1, lutThird); //拥有三通道的LUT查找表矩阵 vectorMat mergeMats; mergeMats.push_back(lutOne); mergeMats.push_back(lutTwo); mergeMats.push_back(lutThree); Mat LutTree; merge(mergeMats, LutTree); //计算图像的查找表 Mat img imread(lena.png); if (img.empty()) { cout 请确认图像文件名称是否正确 endl; return -1; } Mat gray, out0, out1, out2; cvtColor(img, gray, COLOR_BGR2GRAY); LUT(gray, lutOne, out0); LUT(img, lutOne, out1); LUT(img, LutTree, out2); imshow(out0, out0); imshow(out1, out1); imshow(out2, out2); waitKey(0); return 0; }15.图像尺寸变换resize()flip()hconcat()vconcat()#include opencv2\opencv.hpp #include iostream using namespace std; using namespace cv; int main() { Mat gray imread(C:/opencv/learnOpenCV/lena.png, IMREAD_GRAYSCALE); Mat smallImg, bigImg0, bigImg1, bigImg2; resize(gray, smallImg, Size(15, 15), 0, 0, INTER_AREA); //先将图像缩小 resize(smallImg, bigImg0, Size(30, 30), 0, 0, INTER_NEAREST); //最近邻差值 resize(smallImg, bigImg1, Size(30, 30), 0, 0, INTER_LINEAR); //双线性差值 resize(smallImg, bigImg2, Size(30, 30), 0, 0, INTER_CUBIC); //双三次差值 Mat img_x, img_y, img_xy; flip(gray, img_x, 0); //沿x轴对称 flip(gray, img_y, 1); //沿y轴对称 flip(gray, img_xy, -1); //先x轴对称再y轴对称 Mat img00 imread(C:/opencv/learnOpenCV/lena00.png); Mat img01 imread(C:/opencv/learnOpenCV/lena01.png); Mat img10 imread(C:/opencv/learnOpenCV/lena10.png); Mat img11 imread(C:/opencv/learnOpenCV/lena11.png); //显示4个子图像 //图像连接 Mat img, img0, img1; //图像横向连接 hconcat(img00, img01, img0); hconcat(img10, img11, img1); //横向连接结果再进行竖向连接 vconcat(img0, img1, img); //显示连接图像的结果 waitKey(0); return 0; }16.图像仿射变换warpAffine()getRotationMatrix2D()getAffineTransform()#include opencv2\opencv.hpp #include iostream using namespace std; using namespace cv; int main() { Mat img imread(C:/opencv/learnOpenCV/lena.png); if (img.empty()) { cout 请确认图像文件名称是否正确 endl; return -1; } Mat rotation0, img_warp0; double angle 30; //设置图像旋转的角度 Size dst_size(img.rows, img.cols); //设置输出图像的尺寸 Point2f center(img.rows / 2.0, img.cols / 2.0); //设置图像的旋转中心 rotation0 getRotationMatrix2D(center, angle, 1); //计算放射变换矩阵 warpAffine(img, img_warp0, rotation0, dst_size); //进行仿射变换 imshow(img_warp0, img_warp0); //根据定义的三个点进行仿射变换 Point2f src_points[3]; Point2f dst_points[3]; src_points[0] Point2f(0, 0); //原始图像中的三个点 src_points[1] Point2f(0, (float)(img.cols - 1)); src_points[2] Point2f((float)(img.rows - 1), (float)(img.cols - 1)); dst_points[0] Point2f((float)(img.rows)*0.11, (float)(img.cols)*0.20); //放射变换后图像中的三个点 dst_points[1] Point2f((float)(img.rows)*0.15, (float)(img.cols)*0.70); dst_points[2] Point2f((float)(img.rows)*0.81, (float)(img.cols)*0.85); Mat rotation1, img_warp1; rotation1 getAffineTransform(src_points, dst_points); //根据对应点求取仿射变换矩阵 warpAffine(img, img_warp1, rotation1, dst_size); //进行仿射变换 imshow(img_warp1, img_warp1); waitKey(0); return 0; }17.图像透视变换getPerspectiveTransform()warpPerspective()#include opencv2\opencv.hpp #include iostream using namespace cv; using namespace std; int main() { Mat img imread(C:/opencv/learnOpenCV/11.png); if (img.empty()) { cout 请确认图像文件名称是否正确 endl; return -1; } Point2f src_points[4]; Point2f dst_points[4]; //通过Image Watch查看的二维码四个角点坐标 src_points[0] Point2f(94.0, 374.0); src_points[1] Point2f(506.0, 381.0); src_points[2] Point2f(1.0, 624.0); src_points[3] Point2f(627.0, 627.0); //期望透视变换后二维码四个角点的坐标 dst_points[0] Point2f(0.0, 0.0); dst_points[1] Point2f(627.0, 0.0); dst_points[2] Point2f(0.0, 627.0); dst_points[3] Point2f(627.0, 627.0); Mat rotation, img_warp; rotation getPerspectiveTransform(src_points, dst_points); //计算透视变换矩阵 warpPerspective(img, img_warp, rotation, img.size()); //透视变换投影 imshow(img, img); imshow(img_warp, img_warp); waitKey(0); return 0; }18.图像中绘制基础图形line()circle()ellipse()rectangle()fillPoly()putText()#include opencv2\opencv.hpp #include iostream using namespace cv; using namespace std; int main() { Mat img Mat::zeros(Size(512, 512), CV_8UC3); //生成一个黑色图像用于绘制几何图形 //绘制圆形 circle(img, Point(50, 50), 25, Scalar(255, 255, 255), -1); //绘制一个实心圆 circle(img, Point(100, 50), 20, Scalar(255, 255, 255), 4); //绘制一个圆 //绘制直线 line(img, Point(100, 100), Point(200, 100), Scalar(255, 255, 255), 2, LINE_4, 0); //绘制一条直线 //绘制椭圆 ellipse(img, Point(300, 255), Size(100, 70), 0, 0, 100, Scalar(255, 255, 255), -1); //绘制实心椭圆的一部分 //绘制矩形 rectangle(img, Point(50, 400), Point(100, 450), Scalar(125, 125, 125), -1); //绘制多边形 Point pp[2][6]; pp[0][0] Point(72, 200); pp[0][1] Point(142, 204); pp[0][2] Point(226, 263); pp[0][3] Point(172, 310); pp[0][4] Point(117, 319); pp[0][5] Point(15, 260); pp[1][0] Point(359, 339); pp[1][1] Point(447, 351); pp[1][2] Point(504, 349); pp[1][3] Point(484, 433); pp[1][4] Point(418, 449); pp[1][5] Point(354, 402); Point pp2[5]; pp2[0] Point(350, 83); pp2[1] Point(463, 90); pp2[2] Point(500, 171); pp2[3] Point(421, 194); pp2[4] Point(338, 141); const Point* pts[3] { pp[0],pp[1],pp2 }; //pts变量的生成 int npts[] { 6,6,5 }; //顶点个数数组的生成 fillPoly(img, pts, npts, 3, Scalar(125, 125, 125), 8); //绘制3个多边形 //生成文字 putText(img, Learn OpenCV 4, Point(100, 400), 2, 1, Scalar(255, 255, 255)); imshow(, img); waitKey(0); return 0; }19.ROI区域截取Range()copyTo()#include opencv2\opencv.hpp #include iostream using namespace cv; using namespace std; int main() { Mat img imread(C:/opencv/learnOpenCV/lena.png); Mat noobcv imread(C:/opencv/learnOpenCV/noobcv.jpg); if (img.empty() || noobcv.empty()) { cout 请确认图像文件名称是否正确 endl; return -1; } Mat ROI1, ROI2, ROI2_copy, mask, img2, img_copy; resize(noobcv, mask, Size(200, 200)); img2 img; //浅拷贝 //深拷贝的方式 img.copyTo(img_copy); //两种在图中截取ROI区域的方式 Rect rect(206, 206, 200, 200); //定义ROI区域 ROI1 img(rect); //截图 ROI2 img(Range(300, 500), Range(300, 500)); //第二种截图方式 img(Range(300, 500), Range(300, 500)).copyTo(ROI2_copy); //深拷贝 mask.copyTo(ROI1); //在图像中加入部分图像 imshow(加入noobcv后图像, img); imshow(深拷贝的img_copy, img_copy); imshow(ROI对ROI2的影响, ROI2); imshow(深拷贝的ROI2_copy, ROI2_copy); circle(img, Point(300, 300), 20, Scalar(0, 0, 255), -1); //绘制一个圆形 imshow(浅拷贝的img2, img2); imshow(画圆对ROI1的影响, ROI1); waitKey(0); return 0; }20.高斯图像金字塔pyrDown()#include opencv2\opencv.hpp #include iostream using namespace cv; using namespace std; int main() { Mat img imread(C:/opencv/learnOpenCV/lena.png); vectorMat Guass; int level 3; Guass.push_back(img); for (int i 0; i level; i) { Mat guass; pyrDown(Guass[i], guass); Guass.push_back(guass); } for (int i 0; i level; i) { string name to_string(i); imshow(name, Guass[i]); } waitKey(0); return 0; }21.拉普拉斯图像金字塔.pyrUp()#include opencv2\opencv.hpp #include iostream using namespace cv; using namespace std; int main() { Mat img imread(C:/opencv/learnOpenCV/lena.png); vectorMat Guass; int level 3; Guass.push_back(img); for (int i 0; i level; i) { Mat guass; pyrDown(Guass[i], guass); Guass.push_back(guass); } vectorMat Lap; for (int i Guass.size()-1; i 0 ; i--) { Mat lap, upGuass; if (i Guass.size() - 1) { Mat down; pyrDown(Guass[i], down); pyrUp(down, upGuass); lap Guass[i] - upGuass; Lap.push_back(lap); } pyrUp(Guass[i], upGuass); lap Guass[i - 1] - upGuass; Lap.push_back(lap); } for (int i 0; i Guass.size(); i) { string name to_string(i); Mat guass, lap; guass Guass[i]; lap Lap[Guass.size() - 1 - i]; imshow(G name, Guass[i]); imshow(L name, Lap[Guass.size() - 1 - i]); } waitKey(0); return 0; }22.创建滑动条createTrackbar()#include opencv2/opencv.hpp #include iostream using namespace std; using namespace cv; void callBack(int value, void*); Mat img; int main() { img imread(C:/opencv/learnOpenCV/lena.png); namedWindow(img); imshow(img, img); int value 100; createTrackbar(百分比, img, value, 600, callBack, 0); waitKey(0); return 0; } void callBack(int value, void*) { float a value / 100.0; Mat img2; img2 img *a; imshow(img, img2); }23.鼠标事件响应setMouseCallBack()MouseCallback()#include opencv2/opencv.hpp #include iostream using namespace std; using namespace cv; Mat img, imgPoint; //全局的图像 Point prePoint; //前一时刻鼠标的坐标用于绘制直线 void mouse(int event, int x, int y, int flags, void*); int main() { img imread(C:/opencv/learnOpenCV/lena.png); if (!img.data) { cout 请确认输入图像名称是否正确 endl; return -1; } img.copyTo(imgPoint); imshow(图像窗口 1, img); imshow(图像窗口 2, imgPoint); setMouseCallback(图像窗口 1, mouse, 0); //鼠标影响 waitKey(0); return 0; } void mouse(int event, int x, int y, int flags, void*) { if (event EVENT_RBUTTONDOWN) //单击右键 { cout 点击鼠标左键才可以绘制轨迹 endl; } if (event EVENT_LBUTTONDOWN) //单击左键输出坐标 { prePoint Point(x, y); cout 轨迹起始坐标 prePoint endl; } if (event EVENT_MOUSEMOVE (flags EVENT_FLAG_LBUTTON)) //鼠标按住左键移动第 3 章 图像基本操作 { //通过改变图像像素显示鼠标移动轨迹 imgPoint.atVec3b(y, x) Vec3b(255, 255, 255); imgPoint.atVec3b(y, x - 1) Vec3b(255, 255, 255); imgPoint.atVec3b(y, x 1) Vec3b(255, 255, 255); imgPoint.atVec3b(y 1, x) Vec3b(255, 255, 255); imgPoint.atVec3b(y 1, x) Vec3b(255, 255, 255); imshow(图像窗口 2, imgPoint); //通过绘制直线显示鼠标移动轨迹 Point pt(x, y); line(img, prePoint, pt, Scalar(255, 255, 255), 2, 5, 0); prePoint pt; imshow(图像窗口 1, img); } }24.图像直方图绘制calcHist()#include opencv2\opencv.hpp #include iostream using namespace cv; using namespace std; int main() { Mat img imread(C:/opencv/learnOpenCV/airplane.jpg); if (img.empty()) { cout 请确认图像文件名称是否正确 endl; return -1; } Mat gray; cvtColor(img, gray, COLOR_BGR2GRAY); //设置提取直方图的相关变量 Mat hist; //用于存放直方图计算结果 const int channels[1] { 0 }; //通道索引 const int bins[1] { 256 }; //直方图的维度其实就是像素灰度值的最大值 float inRanges[2] { 0,255 }; const float* ranges[1] { inRanges }; //像素灰度值范围 calcHist(gray, 1, channels, Mat(), hist, 1, bins, ranges); //计算图像直方图 //准备绘制直方图 int hist_w 512; int hist_h 200; int width 2; Mat histImage Mat::zeros(hist_h, hist_w, CV_8UC3); //for (int i 1; i hist.rows; i) //{ // rectangle(histImage, Point(width*(i - 1), hist_h - 1), // Point(width*i - 1, hist_h - cvRound(hist.atfloat(i - 1) / 15)), // Scalar(255, 255, 255), -1); //} Mat hist_INF; normalize(hist, hist_INF, 1, 0, NORM_INF, -1, Mat()); for (int i 1; i hist_INF.rows; i) { rectangle(histImage, Point(width*(i - 1), hist_h - 1), Point(width*i - 1, hist_h - cvRound(hist_h*hist_INF.atfloat(i - 1)) - 1), Scalar(255, 255, 255), -1); } imshow(histImage, histImage); imshow(gray, gray); waitKey(0); return 0; }25.直方图均衡化equalizeHist()#include opencv2\opencv.hpp #include iostream using namespace cv; using namespace std; void drawHist(Mat hist, int type, string name) //归一化并绘制直方图函数 { int hist_w 512; int hist_h 400; int width 2; Mat histImage Mat::zeros(hist_h, hist_w, CV_8UC3); normalize(hist, hist, 1, 0, type, -1, Mat()); for (int i 1; i hist.rows; i) { rectangle(histImage, Point(width*(i - 1), hist_h - 1), Point(width*i - 1, hist_h - cvRound(hist_h*hist.atfloat(i - 1)) - 1), Scalar(255, 255, 255), -1); } imshow(name, histImage); } //主函数 int main() { Mat img imread(C:/opencv/learnOpenCV/histMatch.png); if (img.empty()) { cout 请确认图像文件名称是否正确 endl; return -1; } Mat gray, hist, hist2; cvtColor(img, gray, COLOR_BGR2GRAY); Mat equalImg; equalizeHist(gray, equalImg); //将图像直方图均衡化 const int channels[1] { 0 }; float inRanges[2] { 0,255 }; const float* ranges[1] { inRanges }; const int bins[1] { 256 }; calcHist(gray, 1, channels, Mat(), hist, 1, bins, ranges); calcHist(equalImg, 1, channels, Mat(), hist2, 1, bins, ranges); drawHist(hist, NORM_INF, hist); drawHist(hist2, NORM_INF, hist2); imshow(原图, gray); imshow(均衡化后的图像, equalImg); waitKey(0); return 0; }26.直方图匹配#include opencv2\opencv.hpp #include iostream using namespace cv; using namespace std; void drawHist(Mat hist, int type, string name) //归一化并绘制直方图函数 { int hist_w 512; int hist_h 400; int width 2; Mat histImage Mat::zeros(hist_h, hist_w, CV_8UC3); normalize(hist, hist, 1, 0, type, -1, Mat()); for (int i 1; i hist.rows; i) { rectangle(histImage, Point(width*(i - 1), hist_h - 1), Point(width*i - 1, hist_h - cvRound(20 * hist_h*hist.atfloat(i - 1)) - 1), Scalar(255, 255, 255), -1); } imshow(name, histImage); } //主函数 int main() { Mat img1 imread(C:/opencv/learnOpenCV/histMatch.png); Mat img2 imread(C:/opencv/learnOpenCV/equalLena.png); if (img1.empty() || img2.empty()) { cout 请确认图像文件名称是否正确 endl; return -1; } Mat hist1, hist2; //计算两张图像直方图 const int channels[1] { 0 }; float inRanges[2] { 0,255 }; const float* ranges[1] { inRanges }; const int bins[1] { 256 }; calcHist(img1, 1, channels, Mat(), hist1, 1, bins, ranges); calcHist(img2, 1, channels, Mat(), hist2, 1, bins, ranges); //归一化两张图像的直方图 drawHist(hist1, NORM_L1, hist1); drawHist(hist2, NORM_L1, hist2); //计算两张图像直方图的累积概率 float hist1_cdf[256] { hist1.atfloat(0) }; float hist2_cdf[256] { hist2.atfloat(0) }; for (int i 1; i 256; i) { hist1_cdf[i] hist1_cdf[i - 1] hist1.atfloat(i); hist2_cdf[i] hist2_cdf[i - 1] hist2.atfloat(i); } //构建累积概率误差矩阵 float diff_cdf[256][256]; for (int i 0; i 256; i) { for (int j 0; j 256; j) { diff_cdf[i][j] fabs(hist1_cdf[i] - hist2_cdf[j]); } } //生成LUT映射表 Mat lut(1, 256, CV_8U); for (int i 0; i 256; i) { // 查找源灰度级为i的映射灰度 // 和i的累积概率差值最小的规定化灰度 float min diff_cdf[i][0]; int index 0; //寻找累积概率误差矩阵中每一行中的最小值 for (int j 1; j 256; j) { if (min diff_cdf[i][j]) { min diff_cdf[i][j]; index j; } } lut.atuchar(i) (uchar)index; } Mat result, hist3; LUT(img1, lut, result); imshow(待匹配图像, img1); imshow(匹配的模板图像, img2); imshow(直方图匹配结果, result); calcHist(result, 1, channels, Mat(), hist3, 1, bins, ranges); drawHist(hist3, NORM_L1, hist3); //绘制匹配后的图像直方图 waitKey(0); return 0; }27.模板匹配matchTemplate()#include opencv2\opencv.hpp #include iostream using namespace cv; using namespace std; int main() { Mat img imread(C:/opencv/learnOpenCV/lena.png); Mat temp imread(C:/opencv/learnOpenCV/lena_face.png); Mat result; matchTemplate(img, temp, result, TM_CCOEFF_NORMED); double maxVal, minVal; Point maxLoc, minLoc; minMaxLoc(result, minVal, maxVal, minLoc, maxLoc); rectangle(img, Point(maxLoc.x, maxLoc.y), Point(maxLoc.x temp.cols, maxLoc.y temp.rows), Scalar(0, 0, 255), 2); imshow(原图像, img); imshow(模板, temp); imshow(result, result); waitKey(0); return 0; }

相关新闻