1、opencv简单的读取和显示图片
如果不设置imread的读入参数,默认读入的为彩色图片
#include#includeusing namespace std; using namespace cv; int main(int argc,char** argv){ Mat src = imread("F:/images/zwj.jpg"); //读取图片 if (src.empty()) { //判断是否找到图片 printf("没有找到图片 "); //输出文字 return -1; } else { namedWindow("input",WINDOW_AUTOSIZE);// 显示窗口命名为input ;WINDOW_AUTOSIZE显示大小为图片自定义大小,且不可以更改大小 imshow("input",src); //显示 waitKey(0);//显示的毫秒时间,如果函数参数0表示显示的时间 destroyAllWindows(); return 0; } }
2、opencv加载一个灰度图像
只要设置imread的参数:IMREAD_GRAYSCALE(PS:彩色图像的参数为:IMREAD_ANYCOLOR)
3、 Mat创建方法
#include#includeusing namespace std; using namespace cv; int main(int argc,char** argv){ Mat src = imread("D:/Program Files/opencv/sources/samples/data/opencv-logo.png",IMREAD_GRAYSCALE); if(src.empty()){ printf("没有此图片,请检查路径是否正确"); return -1; } else { namedWindow("图片",WINDOW_AUTOSIZE); imshow("图片",src); int width = src.cols;//宽带 int higth = src.rows;//高度 int dim = src.channels();//查看维度 int d = src.depth();// int t = src.type();//图像类型 if(t==CV_8UC3){ printf("width: %d|,higth : %d dim %d", width, higth, dim); printf("深度:%d,类型:%d", d, d); } //怎么创建Mat //创建方法一 Mat t1 = Mat(256,256,CV_8UC3); t1 = Scalar(0,0,255); imshow("t1",t1); //创建方法二 Mat t2 = Mat(512, 512, CV_8UC3); t2 = Scalar(255,0,255); imshow("t2",t2); //创建方法三 Mat t3 = Mat::zeros(Size(256,256),CV_8UC3); //3 = Scalar(255,0,0); imshow("t3",t3); //创建方法四:复制克隆方法 Mat t4 = src.clone(); imshow("t4",t4); //创建方法五 Mat t5 = Mat::zeros(src.size(), src.type());//创建一个和原图大小一样,类型一样的图 imshow("t5", t5); waitKey(0); destroyAllWindows(); return 0; } }
4、opencv如何遍历所有像素点
普通方法:基于数组遍历
//如何遍历访问所有Mat的像素值 #include#includeusing namespace std; using namespace cv; int main(int argc,char** argv){ Mat src = imread("D:/Program Files/opencv/sources/samples/data/opencv-logo.png",IMREAD_GRAYSCALE); if (src.empty()) { printf("没找到图片,请检查路径"); return -1; } else { namedWindow("图像",WINDOW_FREERATIO); imshow("图像",src); //遍历访问像素值 //首先知道图像的长高 int width = src.cols; int higth = src.rows; int dim = src.channels(); for (int row = 0; row < higth;row++) { for (int col = 0; col < width;col++) { if (dim==3) { Vec3b pixel=src.at(row, col);//字节类型3通道的Vec3b,int 类型Vec3i获得 int blue = pixel[0]; int green = pixel[1]; int red = pixel[2]; src.at(row, col)[0] = 255 - blue; src.at(row, col)[1] = 255 - green; src.at(row, col)[2] = 255 - red; } else if(dim==1){ int pv = src.at(row, col);//单通道的灰度是char类型 src.at(row, col) = (255 - pv); } } } imshow("像素测试图像", src); waitKey(0); destroyAllWindows(); return 0; } }
高级遍历方式:基于指针遍历方式
//如何遍历访问所有Mat的像素值 #include#includeusing namespace std; using namespace cv; int main(int argc,char** argv){ Mat src = imread("D:/Program Files/opencv/sources/samples/data/opencv-logo.png",IMREAD_ANYCOLOR); if (src.empty()) { printf("没找到图片,请检查路径"); return -1; } else { namedWindow("图像",WINDOW_FREERATIO); imshow("图像",src); //遍历访问像素值 //首先知道图像的长高 int width = src.cols; int higth = src.rows; int dim = src.channels(); //基于指针的遍历方式 Mat result = Mat::zeros(src.size(),src.type()); // 基于数组遍历方式 for (int row = 0; row < higth;row++) { uchar*curr_row = src.ptr(row);//获取当前行的指针 uchar*result_row = result.ptr(row); for (int col = 0; col < width;col++) { if (dim==3) { int blue = *curr_row++; int green = *curr_row++; int red = *curr_row++; *result_row++ = blue; *result_row++ = green; *result_row++ = red; } else if(dim==1){ int pv = *curr_row++; *result_row++ = pv; } } } imshow("像素测试图像", result); waitKey(0); destroyAllWindows(); return 0; } }
5、opencv进行图像腐蚀和膨胀
#include#includeusing namespace std; using namespace cv; int main(int argc, char** argv) { Mat src = imread("D:/images/smarties.png"); //读取图片 if (src.empty()) { //判断是否找到图片 printf("没有找到图片 "); //输出文字 } else { namedWindow("原图", WINDOW_AUTOSIZE);// 显示窗口命名为input ;WINDOW_AUTOSIZE显示大小为图片自定义大小,且不可以更改大小 imshow("原图", src); //显示 Mat str1= getStructuringElement(MORPH_RECT,Size(50, 50)); Mat fsImg; erode(src,fsImg,str1); imshow("腐蚀图像",fsImg); Mat str2 = getStructuringElement(MORPH_RECT, Size(20, 20)); Mat pzImg; dilate(src, pzImg, str2); imshow("膨胀图像", pzImg); waitKey(0);//显示的毫秒时间,如果函数参数0表示显示的时间 destroyAllWindows(); return 0; } }
6、opencv均值滤波
#include#includeusing namespace std; using namespace cv; int main(int argc,char** argv) { Mat src = imread("F:/images/zwj.jpg"); if (src.empty()) { printf("没有找到图像,请检查路径是否正确"); return -1; } else { //显示原图 namedWindow("原图像",WINDOW_FREERATIO); imshow("原图像",src); //均值滤波 Mat dstImg; blur(src,dstImg,Size(20,20)); imshow("滤波后的图像",dstImg); waitKey(0); destroyAllWindows(); return 0; } }
7、opencv边缘检测
#include#includeusing namespace std; using namespace cv; int main(int argc,char** argv) { Mat src = imread("F:/images/zwj.jpg"); if (src.empty()) { printf("未发现图像,请检查图片路径"); return -1; } else { imshow("原图像",src); //边缘检测 Mat dstImg, edge, grayImg; dstImg.create(src.size(), src.type());//创建一个和src同类型大小的图像 cvtColor(src, grayImg, COLOR_BGR2GRAY); //降噪 blur(grayImg,edge,Size(3,3)); //边缘检测 Canny(edge, edge, 3, 9, 3); //显示 imshow("边缘检测图",edge); waitKey(0); destroyAllWindows(); return 0; } }
8、opencv读取视频
#include#includeusing namespace std; using namespace cv; int main(int argc,char** argv) { VideoCapture capture("D:/Program Files/opencv/sources/samples/data/vtest.avi"); while (true) { Mat frame;//定义一个Mat变量存储每一个帧图像 capture >> frame; imshow("读取视频",frame);//显示当前帧数 waitKey(30);//延时30ms } return 0; }
9、opencv对视频进行Canny边缘检测处理
#include#includeusing namespace std; using namespace cv; int main(int argc, char** argv) { VideoCapture capture("D:/Img/蔡徐坤.mp4"); Mat edge; while (true) { // 读取原图像 Mat frame;//定义一个Mat变量存储每一个帧图像 capture >> frame;//读取当前帧图片 //将原图像转换为灰度 cvtColor(frame,edge,COLOR_BGR2GRAY);//转换为灰度图像 //滤波降噪处理 blur(edge,edge,Size(7,7)); //边缘检测Canny算子 Canny(edge,edge,0,30,3); imshow("Canny边缘检测算子处理后的图像",edge); waitKey(1);//延时1ms } destroyAllWindows(); return 0; }
10、opencv对图像进行加减乘除操作
#include#includeusing namespace std; using namespace cv; int main(int argc, int argv) { Mat src1 = imread("D:/Program Files/opencv/sources/samples/data/LinuxLogo.jpg"); Mat src2= imread("D:/Program Files/opencv/sources/samples/data/WindowsLogo.jpg"); if (src1.empty()&&src2.empty()) { printf("没有找到图像,请检查路径是否正确"); return -1; } else { imshow("demo1", src1); imshow("demo2", src2); //代码演示 Mat dst1; add(src1, src2,dst1); imshow("加法",dst1); //减法操作 Mat dst2; subtract(src1, src2, dst2); imshow("减法", dst2); //乘法操作 Mat dst3; multiply(src1, src2, dst3); imshow("乘法", dst3); //除法操作 Mat dst4; divide(src1, src2, dst4); imshow("除法操作", dst4); waitKey(0); destroyAllWindows(); return 0; } }
11、opencv调用摄像头
#include#include#include#include#includeusing namespace cv; using namespace std; int main(int, char**) { Mat frame; VideoCapture cap; int deviceID = 0; int apiID = 0; cap.open(deviceID, apiID); while (true) { cap.read(frame); if (frame.empty()) { cerr << "错误,空白帧\n"; break; } imshow("调用摄像头", frame); waitKey(4); } return 0; }
12、opencv获取图像最大值像素点、最小值像素点、均值和方差
#include#includeusing namespace cv; using namespace std; int main(int argc,char** argv) { Mat src = imread("F:/images/zwj.jpg",IMREAD_GRAYSCALE); if (src.empty()) { printf("没有图片"); return -1; } else { namedWindow("input", WINDOW_AUTOSIZE); imshow("input", src); int w = src.cols;//宽 int h = src.rows;//高 int dim = src.channels();//维度 printf("w:%d,h:%d,dim:%d\n",w,h,dim);// double min_val; double max_val; Point maxloc; Point minloc; minMaxLoc(src,&min_val,&max_val,&minloc,&maxloc);//获取图像像素点的最大值和最小值,以及索引位置 printf("min:%.2f,max:%.2f\n",min_val,max_val);//打印最大最小像素点 printf("minX:%d,minY:%d maxX:%d,maxY:%d\n",minloc.x, minloc.y, maxloc.x, maxloc.y);//打印最大最小像素点的位置 //均值 Scalar s = mean(src); printf("均值:%.2f\n",s[0]);//因为灰度是单通道的s[0],PS:彩色图像是三通道的s[0],s[1],s[2] //方差 Mat mm,mstd; meanStdDev(src,mm,mstd);//均值和方差 int rows = mstd.rows; int cols = mstd.cols; printf("rows:%d,cols:%d\n",rows,cols); printf("均值:%.3f,方差:%.3f\n",mm.at(0,0),mstd.at(0,0)); waitKey(0); destroyAllWindows(); return 0; } }
13、opencv画线、矩形、椭圆、圆形
#include#includeusing namespace cv; using namespace std; int main(int argc, char** argv) { Mat canvas = Mat::zeros(Size(512,512),CV_8UC3); namedWindow("画布图像", WINDOW_AUTOSIZE); imshow("画布图像", canvas); //相关绘制 //线 line(canvas,Point(10,10),Point(400,400),Scalar(0,0,255),2,LINE_8);//画布、起、始点、颜色、线宽、渲染方式 //矩形 Rect rect(100,100,200,200);//绘制矩形 rectangle(canvas,rect,Scalar(255,0,0),3,8); circle(canvas, Point(256, 256), 100, Scalar(0,255, 0),-3, 8);//画布、圆心、半径、颜色、线宽、渲染方式 //椭圆 RotatedRect rrt; rrt.center = Point2f(256,256); rrt.angle =CV_PI/4;// pi/4 rrt.size=Size(100,200); ellipse(canvas, rrt, Scalar(0, 255, 255), -1, 8); //注:线宽<0则是填充图案 imshow("画线段",canvas); waitKey(0); destroyAllWindows(); return 0; }
14、opencv分离图像通道
#include#includeusing namespace cv; using namespace std; int main(int argc, char** argv) { Mat src = imread("F:/images/zwj.jpg"); if (src.empty()) { printf("没有图片"); return -1; } else { namedWindow("原图", WINDOW_AUTOSIZE); vectormv; split(src,mv);//分离通道 int size = mv.size(); printf("通道数目:%d\n",size);//打印通道数目 imshow("blue",mv[0]);//第一通道 imshow("green:", mv[1]);//第二通道 imshow("red", mv[2]);//第三通道 mv[1] = Scalar(0); Mat dst; merge(mv,dst);//合并 imshow("result",dst); imshow("原图", src); waitKey(0); destroyAllWindows(); return 0; } }
15、opencv好玩的代码:学了这么多觉得有点枯燥,做点新玩意
注意:因为opencv不支持中文,解决方案见:这位大佬的,把源码拷贝过来就行了
#include#include "putText.h" #includeusing namespace cv; using namespace std; int main(int argc, char** argv) { Mat image = Mat::zeros(Size(1000, 800), CV_8UC3); int row = image.rows; int col = image.cols; //提前声明坐标变量 int x1 = 0, y1 = 0; RNG rng; while (true) { x1 = (int)rng.uniform(0, col-1); y1 = (int)rng.uniform(0, row-1); //image = Scalar(0,0,0); putTextZH(image,"帅", Point(x1, y1),Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), rng.uniform(0,200),"宋体"); imshow("别人都夸我帅", image); char c = waitKey(100); if (c == 27) { break; } } waitKey(0); destroyAllWindows(); return 0; }
16、opencv绘制直方图
#include#includeusing namespace std; using namespace cv; int main(int argc,char** argv) { Mat src = imread("F:/images/zwj.jpg"); if (src.empty()) { cout << "没有图片请 检查路径" << endl; return -1; } else { namedWindow("原图像",WINDOW_AUTOSIZE); imshow("原图像",src); vectormv; split(src,mv); //计算直方图 int histSize = 256; Mat b_hist, g_hist, r_hist; float range[] = {0,255}; const float* histRanges= { range}; calcHist(&mv[0],1,0,Mat(),b_hist,1,&histSize,&histRanges,true,false); calcHist(&mv[1],1,0,Mat(),g_hist,1,&histSize,&histRanges,true, false); calcHist(&mv[2],1,0,Mat(),r_hist,1,&histSize,&histRanges,true, false); Mat result = Mat::zeros(Size(src.rows,src.cols),CV_8UC3); int margin = 50; int h = result.rows; int nm = result.rows - 2 * margin; normalize(b_hist ,b_hist, 0, nm, NORM_MINMAX, -1, Mat()); normalize(g_hist, g_hist, 0, nm, NORM_MINMAX, -1, Mat()); normalize(r_hist, r_hist, 0, nm, NORM_MINMAX, -1, Mat()); float step = 500 / 256; for (int i = 0; i < 255; i++) { line(result, Point(step*i, 50 + (nm - b_hist.at(i, 0))), Point(step*(i + 1), 50 + (nm - b_hist.at(i + 1, 0))), Scalar(255, 0, 0), 2, 8, 0); line(result, Point(step*i, 50 + (nm - g_hist.at(i, 0))), Point(step*(i + 1), 50 + (nm - g_hist.at(i + 1, 0))), Scalar(0, 255, 0), 2, 8, 0); line(result, Point(step*i, 50 + (nm - r_hist.at(i, 0))), Point(step*(i + 1), 50 + (nm - r_hist.at(i + 1, 0))), Scalar(0, 0, 255), 2, 8, 0); } imshow("demo",result); waitKey(0); return 0; } }
17、openCV卷积操作 (根据原理写代码,openCV的卷积API为blur)
#include#includeusing namespace std; using namespace cv; int main(int argv,char** argc) { Mat src = imread("F:/images/zwj.jpg"); if(src.empty()){ cout << "没有找到图片,请检查路径是否正确" << endl; return -1; } namedWindow("原图",WINDOW_AUTOSIZE); imshow("原图",src); int w = src.cols; int h = src.rows; Mat result = src.clone(); for ( int row = 1; row < w-1; row++) { for (int col = 1; col < h-1; col++) { //3*3的卷积核 int sb = src.at(row, col)[0] + src.at(row - 1, col - 1)[0] + src.at(row - 1, col)[0] + src.at(row - 1, col + 1)[0] +src.at(row, col-1)[0]+ src.at(row, col+1)[0]+ src.at(row+1, col-1)[0]+ src.at(row+1, col)[0]+ src.at(row+1, col+1)[0]; int sg = src.at(row, col)[1] + src.at(row - 1, col - 1)[1] + src.at(row - 1, col)[1] + src.at(row - 1, col + 1)[1] + src.at(row, col - 1)[1] + src.at(row, col + 1)[1] + src.at(row + 1, col - 1)[1] + src.at(row + 1, col)[1] + src.at(row + 1, col + 1)[1]; int sr = src.at(row, col)[2] + src.at(row - 1, col - 1)[2] + src.at(row - 1, col)[2] + src.at(row - 1, col + 1)[2] + src.at(row, col - 1)[2] + src.at(row, col + 1)[2] + src.at(row + 1, col - 1)[2] + src.at(row + 1, col)[2] + src.at(row + 1, col + 1)[2]; result.at(row, col)[0] = sb/9 ; result.at(row, col)[1] = sg/9; result.at(row, col)[2] = sr/9; } } imshow("卷积",result); waitKey(0); destroyAllWindows(); return 0; }