导入照片,视频,调用摄像头
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/ 导入图片 //
//void main() {
//
// string path = "Resources/test.png";
// Mat img = imread(path);
// imshow("Image", img);
// waitKey(0);
//
//}
/// 导入视频 //
//void main() {
//
// string path = "Resources/test_video.mp4";
// VideoCapture cap(path);
// Mat img;
//
// while (true) {
//
// cap.read(img);
// imshow("Image", img);
// waitKey(20);
// }
//}
/// 网络摄像头 //
void main() {
VideoCapture cap(0);//无外接摄像头用0
Mat img;
while (true) {//由于是一个连续的动画,所以要用一个循环
cap.read(img);
imshow("Image", img);
waitKey(1);
}
}
cvtColor函数:RGB类型的彩色图片转化为灰度图、二值图、HSV、HSI等颜色制式,opencv提供了cvtColor()函数来实现这些功能。
C++: void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 );
参数解释:
. InputArray src: 输入图像即要进行颜色空间变换的原图像,可以是Mat类
. OutputArray dst: 输出图像即进行颜色空间变换后存储图像,也可以Mat类
. int code: 转换的代码或标识,即在此确定将什么制式的图片转换成什么制式的图片,后面会详细将
. int dstCn = 0: 目标图像通道数,如果取值为0,则由src和code决定
具体可参考:cvtColor()函数的具体使用方法
腐蚀与膨胀
dilate函数来实现膨胀操作
opencv提供erode来实现腐蚀操作
具体可参考:腐蚀与膨胀
/ 五个基本功能 //
void main() {
string path = "Resources/test.png";
Mat img = imread(path);
Mat imgGray,imgBlur, imgCanny, imgDil, imgErode;
cvtColor(img,imgGray,COLOR_BGR2GRAY);//转成灰度图
GaussianBlur(img, imgBlur, Size(7, 7), 5, 0);//高斯模糊
Canny(imgBlur, imgCanny, 25, 75);//边缘检测,后面两个是边缘值
Mat Kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
dilate(imgCanny, imgDil, Kernel);//膨胀,亮处膨胀
erode(imgDil, imgErode, Kernel);
imshow("Image", img);
imshow("灰度图", imgGray);
imshow("高斯模糊", imgBlur);
imshow("高斯模糊", imgCanny);
imshow("膨胀", imgDil);
imshow("腐蚀", imgErode);
waitKey(0);
}
调整图片大小和图片裁剪
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);//调整图片大小
Rect roi(100, 100,300,250);//图片裁剪
imgCrop = img(roi);
imshow("Image", img);
imshow("调整图片大小", imgResize);
imshow("裁剪图片", imgCrop);
waitKey(0);
}
绘制形状和文字:Circle函数
cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int lineType=8, int shift=0)
参数含义:
img为源图像指针;
center为画圆的圆心坐标;
radius为圆的半径;
color为设定圆的颜色,规则根据B(蓝)G(绿)R(红);
thickness 如果是正数,表示组成圆的线条的粗细程度,否则,表示圆是否被填充;
line_type 线条的类型,默认是8;
shift 圆心坐标点和半径值的小数点位数。
/ 绘制形状和文字 //
void main() {
Mat img(512, 512, CV_8UC3, Scalar(255, 255, 255));//创建一个蓝色图像
circle(img, Point(256, 256), 155, Scalar(0, 69, 255),FILLED);//画圆,Point这里则是指圆心点的坐标
rectangle(img, Point(130, 226), Point(382, 286), Scalar(255, 0, 255), FILLED);//画矩形,Point这里则是左上角和右下角坐标,3指的是线条厚度,FILLED则是填充,Scalar是颜色规则,根据B(蓝)G(绿)R(红)
line(img, Point(130, 296), Point(382, 296), Scalar(255, 255, 255), 2);//画线
putText(img, "别摆了,张同学", Point(137, 262), FONT_HERSHEY_DUPLEX, 0.75, Scalar(255, 0, 0), 5);//写字
imshow("image", img);
waitKey(0);
}
翘曲图像:
1、获取透视变换矩阵函数GetPerspectiveTransform
CV_EXPORTS Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU);
参数释义
参数 src 源图像四边形顶点坐标.
参数 dst 目标图像对应的四边形顶点坐标.
参数 solveMethod 传递给cv::solve(#DecompTypes)的计算方法,默认是DECOMP_LU
参考 findHomography, warpPerspective, perspectiveTransform
详情请看:https://blog.csdn.net/jndingxin/article/details/109335687
2、warpPerspective()函数:对图像进行透视变换,就是变形
C++: void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
参数详解:
InputArray src:输入的图像
OutputArray dst:输出的图像
InputArray M:透视变换的矩阵
Size dsize:输出图像的大小
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
float w = 250, h = 350;
Mat matrix, imgWarp;
/ 翘曲图像 //
void main() {
String path = "D:/opencv/opencv451/opencv451/Resources/cards.jpg";
Mat img = imread(path);
Point2f src[4] = { {529,142},{771,190},{405,395},{674,457} };//Point2f表示浮点数
Point2f dst[4] = { {0.0f,0.0f},{w,0.0f},{0.0f,h},{w,h} };//Point2f表示浮点数
matrix = getPerspectiveTransform(src, dst);
warpPerspective(img, imgWarp, matrix, Point(w,h));
//确定src坐标是否正确
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);
}
效果展示:
颜色检测:
inRange()函数:
函数原型(C++):
void inRange(InputArray src, InputArray lowerb,InputArray upperb, OutputArray dst);
参数解释:
参数1:输入要处理的图像,可以为单通道或多通道。
参数2:包含下边界的数组或标量。
参数3:包含上边界数组或标量。
参数4:输出图像,与输入图像src 尺寸相同且为CV_8U 类型。
请注意:该函数输出的dst是一幅二值化之后的图像。
详情请看:OpenCV中的inRange()_Arcobaleno-CSDN博客_inrange opencv
createTrackbar()
createTrackbar是Opencv中的API,其可在显示图像的窗口中快速创建一个滑动控件,用于手动调节阈值,具有非常直观的效果。
CV_EXPORTS int createTrackbar(const string& trackbarname, const string& winname,
int* value, int count,
TrackbarCallback onChange = 0,
void* userdata = 0);
形式参数二、winname:滑动空间用于依附的图像窗口的名称;
形式参数三、value:初始化阈值;
形式参数四、count:滑动控件的刻度范围;
形式参数五、TrackbarCallback是回调函数,
详情请看:createTrackbar使用方法及步骤_mysee1989的专栏-CSDN博客_createtrackbar函数
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat imghsv, mask;
int hmin = 0, smin=0, vmin=0;//如何确定这6个值,每次都更改所有这些再次运行很痛苦 -->创建跟踪栏(使我们可以实时更改这些值)
int hmax = 179, smax = 255, vmax = 255;
/ 颜色检测 //
void main() {
String path = "D:/opencv/opencv451/opencv451/Resources/shapes.png";
Mat img = imread(path);
cvtColor(img, imghsv, COLOR_BGR2HSV);//以hsv颜色输出,//转换图像到HSV空间,在其中查找颜色更加容易
namedWindow("Trackbars", (640, 200)); //(640, 200)是尺寸
createTrackbar("Hue Min", "Trackbars", &hmin, 179);//对于hue色相饱和度最大180,对于另外两个色相饱和度最大255
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);//在hsv图像中检测lower-upper范围内的图像mask
imshow("Image", img);
imshow("img hsv", imghsv);
imshow("img mask", mask);
waitKey(1);
}
}
检测形状或图像中的轮廓
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
///检测形状或图像中的轮廓//
void getContours(Mat imgDil, Mat img) {//imgDil是传入的扩张边缘的图像用来查找轮廓,img是要在其上绘制轮廓的图像
vector<vector<Point>> contours;//轮廓检测到的轮廓。每个轮廓线存储为一个点的向量
vector<Vec4i> hierarchy;//包含关于映像拓扑的信息 typedef Vec<int, 4> Vec4i;具有4个整数值
//在二值图像中查找轮廓。该函数利用该算法从二值图像中提取轮廓
findContours(imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
drawContours(img, contours, -1, Scalar(255, 0, 255), 2);//img:要绘制轮廓在什么图片上,contours:要绘制的轮廓,-1定义要绘制的轮廓号(-1表示所有轮廓),Saclar表示轮廓颜色,2表示厚度
//过滤器:通过轮廓面积来过滤噪声
vector<vector<Point>> conPoly(contours.size());//conploy的数量应小于contours
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) {//轮廓面积>1000才绘制
//计算轮廓周长或凹坑长度。该函数计算了曲线长度和封闭的周长。
float peri = arcLength(contours[i], true);//计算封闭轮廓周长
approxPolyDP(contours[i], conPoly[i], 0.02*peri, true);//以指定的精度近似多边形曲线。第二个参数conPloy[i]存储近似的结果,是输出。
boundRect[i] = boundingRect(conPoly[i]);//计算边界矩形
int objCor = (int)conPoly[i].size();//找近似多边形的角点,三角形有3个角点,矩形/正方形有4个角点,圆形>4个角点
cout << objCor << endl;
if (objCor == 3) { objectType = "Tri"; }
else if (objCor == 4) {
float aspRatio = (float)boundRect[i].width / (float)boundRect[i].height;//宽高比
if (aspRatio > 0.95 && aspRatio < 1.05) { objectType = "Square"; }//正方形的宽高比不会正好等于1
else objectType = "Rect";
}
else if (objCor > 4) { objectType = "Circle"; }
drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);
rectangle/*绘制边界矩形*/(img, boundRect[i].tl()/*tl():topleft矩形左上角坐标*/, boundRect[i].br()/*br():bottom right矩形右下角坐标*/, 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;
//图像的预处理
cvtColor(img, imgGray, COLOR_BGR2GRAY);//转成灰度图
GaussianBlur(imgGray, imgBlur, Size(7, 7), 5, 0);//高斯模糊
Canny(imgBlur, imgCanny, 25, 75);//边缘检测,后面两个是边缘值
Mat Kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
dilate(imgCanny, imgDil, Kernel);//膨胀,亮处膨胀
getContours(imgDil,img);
imshow("Image", img);
imshow("灰色", imgGray);
imshow("模糊", imgBlur);
imshow("边缘检测", imgCanny);
imshow("膨胀", imgDil);
waitKey(0);
}
运行结果:
人脸检测:基于已经训练好的模型,基于照片
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/// 人脸检测 //
void main() {
string path = "Resources/test.png";
Mat img = imread(path);
CascadeClassifier faceCascade;/*用于对象检测的级联分类器类*/
faceCascade.load("Resources/haarcascade_frontalface_default.xml");//从文件加载分类器(已经训练好的模型)
if (faceCascade.empty()) { cout << "XML file not loaded" << endl; }//判断文件是否调用,存在
//创建矩形向量
vector<Rect> faces;
//人脸级联点检测多尺度法
faceCascade.detectMultiScale(img, faces, 1.1, 10);//在输入图像中检测不同大小的对象。检测到的对象将以矩形列表的形式返回。img/*输入*/, faces/*输出*/, 1.1/*比例因子*/, 10/*最小邻居*/
for (int i = 0; i < faces.size(); i++) {
rectangle(img, faces[i].tl()/*左上角*/, faces[i].br()/*右下角*/, Scalar(255, 0, 255), 3);//绘制矩形
}
imshow("Image", img);
waitKey(0);
}