赞
踩
对于C++ 不熟悉的伙伴,强推这版学习资源!
B站学习资源:4h上手C++版Opencv
安装opencv包以及添加包含目录、库目录和附加依赖项看视频即可
以下是我的学习B站视频和知乎大神笔记整理与自己所在领域——医学图像处理相关的实践和学习笔记!
示例:
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream>//输入输出流 using namespace cv; using namespace std; / Images // void main() { string path = "Resources/test.png"; //1.读取:imread读取到Mat类型的 img中 Mat img = imread(path); //检测image有无数据,无数据 img.empty()返回真 if (img.empty()) { cout << "Could not open or find the image" << endl; return -1; } cout << "图像的行数为: " << image1.rows << endl; //获取图像的高度,行数; cout << "图像的列数为: " << image1.cols << endl; //获取图像的宽度,列数; cout << "图像的通道数为: " << image1.channels() << endl; //获取图像的通道数,彩色图=3,灰度图=1; cout << "图像的尺寸为: " << image1.size << endl; //获取图像的尺寸,行*列; //2.保存:imwrite保存图像为png格式 imwrite("Resources/test_save.png", img); //3.显示:imshow窗口显示图像 imshow("Image", img); waitKey(0); } /// Video // //void main() { // // string path = "Resources/test_video.mp4"; // VideoCapture cap(path); // Mat img; // // while (true) { // // cap.read(img); // imshow("Image", img); // waitKey(20); // } //} / Webcam // //void main() { // // VideoCapture cap(0); // Mat img; // // while (true) { // // cap.read(img); // imshow("Image", img); // waitKey(1); // } //}
imread读取图像的方式有三种:
① 彩色:
imread(path, IMREAD_COLOR);
or
imread(path, 1);
②灰度:
imread(path, IMREAD_GRAYSCALE);
or
imread(path, 0);
③alpha通道:
为实现图形的透明效果,采取在图形文件的处理与存储中附加上另一个8位信息的方法,这个附加的代表图形中各个素点透明度的通道信息就被叫做Alpha通道。Alpha通道使用8位二进制数,就可以表示256级灰度,即256级的透明度。
imread(path, IMREAD_UNCHANGED);
or
imread(path, -1);
基本的图像处理操作(依次增加操作):
图像转换(cvtColor)
图像模糊(GaussianBlur)
图像边缘检测(Canny)
图像边缘扩大(dilate)
图像边缘侵蚀(erode)\
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; /// Basic Functions // void main() { string path = "Resources/test.png"; Mat img = imread(path); Mat imgGray, imgBlur, imgCanny, imgDil, imgErode; cvtColor(img, imgGray, COLOR_BGR2GRAY); //BGR——GRAY GaussianBlur(imgGray, imgBlur, Size(7, 7), 5, 0); // 高斯模糊 Size(7, 7), 5, 控制模糊程度 Canny(imgBlur, imgCanny, 25,75); // 边缘检测,使用前常进行模糊处理 ,75 控制边缘数(越大边缘越少) //Q:边缘检测后部分边缘没有被完全填充 Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); //创建膨胀内核 dilate(imgCanny, imgDil, kernel); //扩大,增加厚度, erode(imgDil, imgErode, kernel); //侵蚀,减小厚度, imshow("Image", img); imshow("Image Gray", imgGray); imshow("Image Blur", imgBlur); imshow("Image Canny", imgCanny); imshow("Image Dilation", imgDil); imshow("Image Erode", imgErode); waitKey(0); }
imshow图像展示:
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; /// Resize and Crop // void main() { string path = "Resources/test.png"; Mat img = imread(path); Mat imgResize, imgCrop; //cout << img.size() << endl; //在终端打印图像宽高 resize(img, imgResize, Size(),0.5,0.5); //可按比例resize,也可以给实际的数字 Rect roi(200, 100, 300, 300); //矩形数据类型 rectangle,定位左上角的点,并给出矩形size imgCrop = img(roi); imshow("Image", img); imshow("Image Resize", imgResize); imshow("Image Crop", imgCrop); waitKey(0); }
圆(circle)
框(rectangle)
线(line)
显示内容(putText)\
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; // Draw Shapes and Text // void main() { // Blank Image Mat img(512, 512, CV_8UC3, Scalar(255, 255, 255)); circle(img, Point(256, 256), 155, Scalar(0, 69, 255),FILLED); //Point表示圆心;155表示圆的半径; FILLED填满,数字表示线的粗细 rectangle(img, Point(130, 226), Point(382, 286), Scalar(255, 255, 255), FILLED); //定义左上角和右下角 line(img, Point(130, 296), Point(382, 296), Scalar(255, 255, 255), 2); putText(img, "Murtaza's Workshop", Point(137, 262), FONT_HERSHEY_DUPLEX, 0.75, Scalar(0, 69, 255),2);//0.75字体大小,2字体粗细 imshow("Image", img); waitKey(0); }
透视转换
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; /// Warp Images // void main() { string path = "Resources/cards.jpg"; Mat img = imread(path); Mat matrix, imgWarp; float w = 250, h = 350; // 目标转换大小 Point2f src[4] = { {529,142},{771,190},{405,395},{674,457} }; //定位目标点 Point2f dst[4] = { {0.0f,0.0f},{w,0.0f},{0.0f,h},{w,h} }; //定义目标点顺序 matrix = getPerspectiveTransform(src, dst); warpPerspective(img, imgWarp, matrix, Point(w, h)); for (int i = 0; i < 4; i++) { circle(img, src[i], 10, Scalar(0, 0, 255), FILLED); } //实心圆圈注释四个角 imshow("Image", img); imshow("Image Warp", imgWarp); waitKey(0); }
图像转换为HSV空间,更容易查找颜色
创建色调可调节滑动窗口
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; /// Color Detection // void main() { string path = "Resources/lambo.png"; Mat img = imread(path); Mat imgHSV, mask; int hmin = 0, smin = 110, vmin = 153; int hmax = 19, smax = 240, vmax = 255; cvtColor(img, imgHSV, COLOR_BGR2HSV); namedWindow("Trackbars", (640, 200)); createTrackbar("Hue Min", "Trackbars", &hmin, 179); createTrackbar("Hue Max", "Trackbars", &hmax, 179); createTrackbar("Sat Min", "Trackbars", &smin, 255); createTrackbar("Sat Max", "Trackbars", &smax, 255); createTrackbar("Val Min", "Trackbars", &vmin, 255); createTrackbar("Val Max", "Trackbars", &vmax, 255); while (true) { Scalar lower(hmin, smin, vmin); Scalar upper(hmax, smax, vmax); //定义标量 inRange(imgHSV, lower, upper, mask); // imshow("Image", img); imshow("Image HSV", imgHSV); imshow("Image Mask", mask); waitKey(1); } }
使用颜色进行对象检测和跟踪
存在问题:图像在放大后像素间存在间隙(为什么在1.2小节中进行膨胀的原因)
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; /// Color Detection // void getContours(Mat imgDil, Mat img) { vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); //drawContours(img, contours, -1, Scalar(255, 0, 255), 2); //扩张,轮廓,层次,方法 vector<vector<Point>> conPoly(contours.size()); vector<Rect> boundRect(contours.size()); for (int i = 0; i < contours.size(); i++) { int area = contourArea(contours[i]); cout << area << endl; string objectType; if (area > 1000) { float peri = arcLength(contours[i], true); approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true); cout << conPoly[i].size() << endl; boundRect[i] = boundingRect(conPoly[i]); int objCor = (int)conPoly[i].size(); if (objCor == 3) { objectType = "Tri"; } else if (objCor == 4) { float aspRatio = (float)boundRect[i].width / (float)boundRect[i].height; cout << aspRatio << endl; if (aspRatio> 0.95 && aspRatio< 1.05){ objectType = "Square"; } else { objectType = "Rect";} } else if (objCor > 4) { objectType = "Circle"; } drawContours(img, conPoly, i, Scalar(255, 0, 255), 2); rectangle(img, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 5); putText(img, objectType, { boundRect[i].x,boundRect[i].y - 5 }, FONT_HERSHEY_PLAIN,1, Scalar(0, 69, 255), 2); } } } void main() { string path = "Resources/shapes.png"; Mat img = imread(path); Mat imgGray, imgBlur, imgCanny, imgDil, imgErode; // Preprocessing cvtColor(img, imgGray, COLOR_BGR2GRAY); GaussianBlur(imgGray, imgBlur, Size(3, 3), 3, 0); Canny(imgBlur, imgCanny, 25, 75); Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); dilate(imgCanny, imgDil, kernel); getContours(imgDil,img); imshow("Image", img); //imshow("Image Gray", imgGray); //imshow("Image Blur", imgBlur); //imshow("Image Canny", imgCanny); //imshow("Image Dil", imgDil); waitKey(0); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。