opencv---c++(2)

 导入照片,视频,调用摄像头

 

#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);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值