【OpenCV】C++ OpenCV 快速入门案例Demo

2023-11-16

目录

1、开发环境配置

1.1 软件版本

1.2 具体配置

1.3 程序框架

2. 程序代码

2.1 Demo头文件 QuickDemo.h

2.2 Demo源代码 QuickDemo.cpp

2.3 测试代码 test450.cpp


1、开发环境配置

1.1 软件版本

VS2017 和 OpenCV4.5.0

1.2 详细配置

                                

 

 

1.3 程序框架

2. 程序代码

2.1 Demo头文件 QuickDemo.h

//QuickDemo.h

#pragma once
#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/dnn.hpp>

using namespace cv;
using namespace cv::dnn;
using namespace std;

class QuickDemo
{
public:
	//空间色彩转换
	void colorSpace_Demo(Mat &image);

	//Mat创建图像
	void matCreation_Demo(Mat &image);

	//图像像素读写
	void pixelVisit_Demo(Mat &image);

	//图像像素算术操作
	void operators_Demo(Mat &image);

	//滚动条调整图像亮度
	void trackingBar_Demo(Mat &image);

	//键盘响应操作图像
	void key_Demo(Mat &image);

	//自带颜色表操作
	void colorStyle_Demo(Mat &image);

	//图像像素的逻辑操作
	void bitwise_Demo(Mat &image);

	//通道分离与合并
	void channels_Demo(Mat &image);

	//图像色彩空间转换
	void inrange_Demo(Mat &image);

	//图像像素值统计
	void pixelStatistic_Demo(Mat &image);

	//图像几何形状绘制
	void drawing_Demo(Mat &image);

	//随机绘制几何形状
	void randomDrawing_Demo();

	//多边形填充与绘制
	void polylineDrawing_Demo();

	//鼠标操作与响应
	void mouseDrawing_Demo(Mat &image);

	//图像像素类型转换与归一化
	void norm_Demo(Mat &image);

	//图像放缩与插值
	void resize_Demo(Mat &image);

	//图像翻转
	void flip_Demo(Mat &image);

	//图像旋转
	void rotate_Demo(Mat &image);

	//视频文件摄像头使用
	void video_Demo(Mat &image);

	//视频文件摄像头使用
	void video2_Demo(Mat &image);

	//视频文件摄像头使用 RTMP拉流
	void video3_Demo(Mat &image);

	//图像直方图
	void histogram_Demo(Mat &image);

	//二维直方图
	void histogram2d_Demo(Mat &image);

	//直方图均衡化
	void histogramEq_Demo(Mat &image);

	//图像卷积操作(模糊)
	void blur_Demo(Mat &image);

	//高斯模糊
	void gaussianBlur_Demo(Mat &image);

	//高斯双边模糊
	void bifilter_Demo(Mat &image);

	//实时人脸检测
	void faceDetection_Demo(Mat &image);
};

 

2.2 Demo源代码 QuickDemo.cpp

//QuickDemo.cpp

#include "QuickDemo.h"

//空间色彩转换Demo
void QuickDemo::colorSpace_Demo(Mat &image)
{
	Mat hsv, gray;

	cvtColor(image, hsv, COLOR_RGB2HSV);
	cvtColor(image, gray, COLOR_RGB2GRAY);
	imshow("HSV", hsv);
	imshow("灰度", gray);
	//imwrite("F:/OpenCV/Image/hsv.png", hsv);
	//imwrite("F:\\OpenCV\\Image\\gray.png", gray);
}

//Mat创建图像
void QuickDemo::matCreation_Demo(Mat &image)
{
	//Mat m1, m2;
	//m1 = image.clone();
	//image.copyTo(m2);
	//imshow("图像1", m1);
	//imshow("图像2", m2);

	Mat m3 = Mat::zeros(Size(400, 400), CV_8UC3);
	m3 = Scalar(255, 255, 0);
	cout << "width:" << m3.cols << " height:" << m3.rows << " channels:" << m3.channels() << endl;
	//cout << m3 << endl;
	imshow("图像3", m3);

	Mat m4 = m3;
	//imshow("图像4", m4);

	m4 = Scalar(0, 255, 255);
	imshow("图像33", m3);

	//imshow("图像44", m4);
}

//图像像素读写
void QuickDemo::pixelVisit_Demo(Mat &image)
{
	int w = image.cols;
	int h = image.rows;
	int dims = image.channels();

	//for (int row = 0; row < h; row++) {
	//	for (int col = 0; col < w; col++) {
	//		if (dims == 1) { //灰度图像
	//			int pv = image.at<uchar>(Point(row, col));
	//			image.at<uchar>(Point(row, col)) = 255 - saturate_cast<uchar>(pv);
	//		}
	//		else if (dims == 3) { //彩色图像
	//			Vec3b bgr = image.at<Vec3b>(row, col);
	//			image.at<Vec3b>(row, col)[0] = 255 - bgr[0];
	//			image.at<Vec3b>(row, col)[1] = 255 - bgr[1];
	//			image.at<Vec3b>(row, col)[2] = 255 - bgr[2];
	//		}
	//	}
	//}

	uchar *img_prt = image.ptr<uchar>();
	for (int row = 0; row < h; row++) {
		for (int col = 0; col < w; col++) {
			for (int dim = 0; dim < dims; dim++) {
				*img_prt++ = 255 - *img_prt;
			}
			//if (dims == 1) { //灰度图像
			//	*img_prt++ = 255 - *img_prt;
			//}
			//else if (dims == 3) { //彩色图像
			//	*img_prt++ = 255 - *img_prt;
			//	*img_prt++ = 255 - *img_prt;
			//	*img_prt++ = 255 - *img_prt;
		}
	}
	imshow("图像像素读写演示", image);
}


//图像像素算术操作
void QuickDemo::operators_Demo(Mat &image)
{
	Mat dst;
	Mat m = Mat::zeros(image.size(), image.type());

	m = Scalar(50, 50, 50);
	add(image, m, dst);
	imshow("加法操作", dst);

	m = Scalar(50, 50, 50);
	subtract(image, m, dst);
	imshow("减法操作", dst);

	m = Scalar(2, 2, 2);
	multiply(image, m, dst);
	imshow("乘法操作", dst);

	m = Scalar(2, 2, 2);
	divide(image, m, dst);
	imshow("除法操作", dst);
	
}


//滚动条回调函数
void onTrack(int b, void* userdata)
{
	Mat image = *((Mat *)userdata);
	Mat dst = Mat::zeros(image.size(), image.type());
	Mat m = Mat::zeros(image.size(), image.type());

	if (b > 100) {
		m = Scalar(b - 100, b - 100, b - 100);
		add(image, m, dst);
	}
	else {
		m = Scalar(100 - b, 100 - b, 100 - b);
		subtract(image, m, dst);
	}

	//addWeighted(image, 1.0, m, 0, b, dst);

	imshow("亮度与对比度调整", dst);
}

//滚动条回调函数
void onContrast(int b, void* userdata)
{
	Mat image = *((Mat *)userdata);
	Mat dst = Mat::zeros(image.size(), image.type());
	Mat m = Mat::zeros(image.size(), image.type());

	double contrast = b / 100.0;
	addWeighted(image, contrast, m, 0.0, 0, dst);

	imshow("亮度与对比度调整", dst);
}

//滚动条调整图像亮度
void QuickDemo::trackingBar_Demo(Mat &image)
{
	int max_value = 200;
	int lightness = 100;
	int contrast_value = 100;

	namedWindow("亮度与对比度调整", WINDOW_AUTOSIZE);

	createTrackbar("Value Bar", "亮度与对比度调整", &lightness, max_value, onTrack, (void *)&image);
	createTrackbar("Contrast Bar", "亮度与对比度调整", &contrast_value, max_value, onContrast, (void *)&image);

	onTrack(lightness, &image);
}


//键盘响应操作图像
void QuickDemo::key_Demo(Mat &image)
{
	Mat dst = Mat::zeros(image.size(), image.type());
	while (true) {
		int c = waitKey(100);
		if (c == 27) {//ESC 退出
			break;
		}
		else if (c == 49) {
			cout << "key #1" << endl;
			cvtColor(image, dst, COLOR_RGB2GRAY);
		}
		else if (c == 50) {
			cout << "key #2" << endl;
			cvtColor(image, dst, COLOR_RGB2HSV);
		}
		else if (c == 51) {
			cout << "key #3" << endl;
			dst = Scalar(50, 50, 50);
			add(image, dst, dst);
		}
		imshow("键盘响应", dst);
	}
}

//自带颜色表操作
void QuickDemo::colorStyle_Demo(Mat &image)
{
	Mat dst = Mat::zeros(image.size(), image.type());
	int index = 0;
	int pixNum = 0;
	while (true) {
		int c = waitKey(2000);
		if (c == 27) {
			break;
		}
		else if (c == 49) {
			String pixPath = "./Image/color";
			pixPath = pixPath.append(to_string(pixNum++));
			pixPath = pixPath.append(".png");
			imwrite(pixPath, dst);
		}
		applyColorMap(image, dst, (index++) % 19);
		imshow("颜色风格", dst);
	}
}

//图像像素的逻辑操作
void QuickDemo::bitwise_Demo(Mat &image)
{
	Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3);
	Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3);
	rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), -1, LINE_8, 0);
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);
	imshow("m1", m1);
	imshow("m2", m2);
	Mat dst;
	bitwise_and(m1, m2, dst);
	imshow("像素位与操作", dst);
	bitwise_or(m1, m2, dst);
	imshow("像素位或操作", dst);
	bitwise_xor(m1, m2, dst);
	imshow("像素位异或操作", dst);
}

//通道分离与合并
void QuickDemo::channels_Demo(Mat &image)
{
	vector<Mat> mv;
	split(image, mv);
	//imshow("蓝色", mv[0]);
	//imshow("绿色", mv[1]);
	//imshow("红色", mv[2]);

	Mat dst;
	vector<Mat> mv2;

	//mv[1] = 0;
	//mv[2] = 0;
	//merge(mv, dst);
	//imshow("蓝色", dst);

	mv[0] = 0;
	mv[2] = 0;
	merge(mv, dst);
	imshow("绿色", dst);

	//mv[0] = 0;
	//mv[1] = 0;
	//merge(mv, dst);
	//imshow("红色", dst);

	int from_to[] = { 0,2,1,1,2,0 };
	mixChannels(&image, 1, &dst, 1, from_to, 3);
	imshow("通道混合", dst);

}

//图像色彩空间转换
void QuickDemo::inrange_Demo(Mat &image)
{
	Mat hsv;
	cvtColor(image, hsv, COLOR_RGB2HSV);
	imshow("hsv", hsv);
	Mat mask;
	inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 255), mask);
	//imshow("mask", mask);
	bitwise_not(mask, mask);
	imshow("mask", mask);

	Mat readback = Mat::zeros(image.size(), image.type());
	readback = Scalar(40, 40, 200);
	image.copyTo(readback, mask);
	imshow("roi区域提取", readback);
}

//图像像素值统计
void QuickDemo::pixelStatistic_Demo(Mat &image)
{
	double minv, maxv;
	Point minLoc, maxLoc;
	vector<Mat> mv;
	split(image, mv);
	for (int i = 0; i < mv.size(); i++) {
		minMaxLoc(mv[i], &minv, &maxv, &minLoc, &maxLoc);
		cout << "No." << i << " min:" << minv << " max:" << maxv << endl;
	}
	Mat mean, stddev;
	meanStdDev(image, mean, stddev);
	cout << "means:" << mean << endl;
	cout << "stddev:" << stddev << endl;
}

//图像几何形状绘制
void QuickDemo::drawing_Demo(Mat &image)
{
	Mat bg = Mat::zeros(image.size(), image.type());

	rectangle(bg, Rect(250, 100, 100, 150), Scalar(0, 0, 255), -1, 8, 0);
	circle(bg, Point(300, 175), 50, Scalar(255, 0, 0), 1, 8, 0);
	line(bg, Point(250, 100), Point(350, 250), Scalar(0, 255, 0), 4, 8, 0);
	line(bg, Point(350, 100), Point(250, 250), Scalar(0, 255, 0), 4, 8, 0);
	ellipse(bg, RotatedRect(Point2f(200.0, 200.0), Size2f(100.0, 200.0), 00.0), Scalar(0, 255, 255), 2, 8);
	imshow("bg", bg);

	Mat dst;
	addWeighted(image, 1.0, bg, 0.3, 0, dst);
	imshow("几何绘制", dst);
}

//随机绘制几何形状
void QuickDemo::randomDrawing_Demo()
{
	Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
	RNG rng(12345);
	int w = canvas.cols;
	int h = canvas.rows;

	while (true) {
		int c = waitKey(10);
		if (c == 27) {
			break;
		}

		int x1 = rng.uniform(0, w);
		int y1 = rng.uniform(0, h);
		int x2 = rng.uniform(0, w);
		int y2 = rng.uniform(0, h);
		int b = rng.uniform(0, 255);
		int g = rng.uniform(0, 255);
		int r = rng.uniform(0, 255);
		//canvas = Scalar(0, 0, 0);
		line(canvas, Point(x1, y1), Point(x2, y2), Scalar(b, g, r), 1, 8, 0);
		imshow("随机绘制演示", canvas);
	}
}

//多边形填充与绘制
void QuickDemo::polylineDrawing_Demo()
{
	Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
	Point p1(100, 100);
	Point p2(350, 100);
	Point p3(450, 280);
	Point p4(320, 450);
	Point p5(80, 400);
	vector<Point> pts;
	pts.push_back(p1);
	pts.push_back(p2);
	pts.push_back(p3);
	pts.push_back(p4);
	pts.push_back(p5);

	Point p11(50, 50);
	Point p12(200, 50);
	Point p13(250, 150);
	Point p14(160, 300);
	Point p15(30, 350);
	vector<Point> pts1;
	pts1.push_back(p11);
	pts1.push_back(p12);
	pts1.push_back(p13);
	pts1.push_back(p14);
	pts1.push_back(p15);

	//fillPoly(canvas, pts, Scalar(255, 255, 0), 8, 0);
	//polylines(canvas, pts, true, Scalar(0, 255, 255), 2, LINE_AA, 0);

	vector<vector<Point>> contours;
	contours.push_back(pts);
	contours.push_back(pts1);
	drawContours(canvas, contours, -1, Scalar(255, 0, 0), 4);

	imshow("多边形", canvas);
}


static void onDraw(int event, int x, int y, int flags, void *userdata)
{
	static Point sp(-1, -1), ep(-1, -1);
	Mat srcImg = *((Mat *)userdata);
	Mat image = srcImg.clone();

	if (event == EVENT_LBUTTONDOWN) {
		sp.x = x;
		sp.y = y;
		//cout << "down_x = " <<sp.x << " dwon_y = " << sp.y << endl;
	}
	else if (event == EVENT_LBUTTONUP) {
		ep.x = x;
		ep.y = y;
		if (ep.x > image.cols) {
			ep.x = image.cols;
		}
		if (ep.y > image.rows) {
			ep.y = image.rows;
		}
		//cout << "up_x = " << ep.x << " up_y = " << ep.y << endl;
		int dx = ep.x - sp.x;
		int dy = ep.y - sp.y;
		if (dx > 0 && dy > 0) {
			Rect box(sp.x, sp.y, dx, dy);
			//rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);
			//imshow("鼠标绘制", image);
			imshow("ROI区域", image(box));
			sp.x = -1;
			sp.y = -1;
		}
			
	}
	else if (event == EVENT_MOUSEMOVE) { 
		if (sp.x > 0 && sp.y > 0) {	
			ep.x = x;
			ep.y = y;
			//cout << "up_x = " << ep.x << " up_y = " << ep.y << endl;

			if (ep.x > image.cols) {
				ep.x = image.cols;
			}
			if (ep.y > image.rows) {
				ep.y = image.rows;
			}
			int dx = ep.x - sp.x;
			int dy = ep.y - sp.y;
			if (dx > 0 && dy > 0) {
				//srcImg.copyTo(image);
				image = srcImg.clone();
				Rect box(sp.x, sp.y, dx, dy);
				rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);
				imshow("鼠标绘制", image);
			}
			
			
		}	
	}
}

//鼠标操作与响应
void QuickDemo::mouseDrawing_Demo(Mat &image)
{
	namedWindow("鼠标绘制", WINDOW_AUTOSIZE);
	setMouseCallback("鼠标绘制", onDraw, (void *)(&image));
	imshow("鼠标绘制", image);
}

//图像像素类型转换与归一化
void QuickDemo::norm_Demo(Mat &image)
{
	Mat dst;
	cout << image.type() << endl;
	//CV_8UC3 转换为 CV_32FC3
	image.convertTo(image, CV_32F);
	cout << image.type() << endl;
	normalize(image, dst, 1.0, 0.0, NORM_MINMAX);
	cout << dst.type() << endl;
	imshow("图像像素归一化", dst);
}

//图像放缩与插值
void QuickDemo::resize_Demo(Mat &image)
{
	Mat zoomSmall, zoomLarge;
	int w = image.cols;
	int h = image.rows;

	resize(image, zoomSmall, Size(w / 2, h / 2), 0, 0, INTER_LINEAR);
	imshow("zoomSamll", zoomSmall);

	resize(image, zoomLarge, Size(w *1.5, h *1.5), 0, 0, INTER_LINEAR);
	imshow("zoomLarge", zoomLarge);
}

//图像翻转
void QuickDemo::flip_Demo(Mat &image)
{
	Mat dst;
	flip(image, dst, 0);//上下翻转(水中倒影)
	//flip(image, dst, 1);//左右翻转(镜子映像)
	//flip(image, dst, -1);//180°翻转(对角线翻转)
	imshow("图像翻转", dst);
}

//图像旋转
void QuickDemo::rotate_Demo(Mat &image)
{
	Mat dst, M;
	int w = image.cols;
	int h = image.rows;
	M = getRotationMatrix2D(Point(w / 2, h / 2), 30, 1.0);
	double cos = abs(M.at<double>(0, 0));
	double sin = abs(M.at<double>(0, 1));
	int nw = cos * w + sin * h;
	int nh = sin * w + cos * h;
	M.at<double>(0, 2) += nw / 2 - w / 2;
	M.at<double>(1, 2) += nh / 2 - h / 2;
	warpAffine(image, dst, M, Size(nw,nh), INTER_LINEAR, 0, Scalar(255, 255, 0));
	imshow("图像旋转", dst);
}

//视频文件摄像头使用
void QuickDemo::video_Demo(Mat &image)
{
	VideoCapture capture(0); 
	//VideoCapture capture("./Image/sample.mp4"); 
	Mat frame;
	
	while (true) {
		capture.read(frame);
		if (frame.empty()) {
			cout << "frame empty" << endl;
			break;
		}
		flip(frame, frame, 1);//视频图像左右翻转
		imshow("摄像头实时监控", frame);

		//TODO:do something ...
		//mouseDrawing_Demo(frame);//视频图像截图
		//colorSpace_Demo(frame);//HSV GRAY
		
		int c = waitKey(10);
		if (c == 27) {
			break;
		}
		
	}

	//release 释放摄像头资源
	capture.release();
}

//视频文件摄像头使用
void QuickDemo::video2_Demo(Mat &image)
{
	//VideoCapture capture(0);
	VideoCapture capture("./Image/lane.avi"); 
	int frame_width = capture.get(CAP_PROP_FRAME_WIDTH);//视频宽度
	int frame_height = capture.get(CAP_PROP_FRAME_HEIGHT);//视频高度
	int count = capture.get(CAP_PROP_FRAME_COUNT);//视频总帧数
	double fps = capture.get(CAP_PROP_FPS);//FPS 一秒刷新帧数
	double fourcc = capture.get(CAP_PROP_FOURCC);//视频编码格式
	cout << "frame width:" << frame_width << endl;
	cout << "frame height:" << frame_height << endl;
	cout << "frames sum:" << count << endl;
	cout << "FPS:" << fps << endl;
	cout << "frame fourcc:" << fourcc << endl;
	VideoWriter writer("./video/lane_save.avi", fourcc, fps, Size(frame_width, frame_height), true);

	Mat frame;

	while (true) {
		capture.read(frame);
		if (frame.empty()) {
			cout << "frame empty" << endl;
			break;
		}
		//flip(frame, frame, 1);//视频图像左右翻转
		imshow("摄像头实时监控", frame);
		writer.write(frame);

		//TODO:do something ...
		//mouseDrawing_Demo(frame);//视频图像截图
		//colorSpace_Demo(frame);//HSV GRAY

		int c = waitKey(10);
		if (c == 27) {
			break;
		}

	}

	//release 释放摄像头资源
	capture.release();
	writer.release();
}

//视频文件摄像头使用 RTMP拉流
void QuickDemo::video3_Demo(Mat &image)
{
	//VideoCapture capture(0);
	VideoCapture vcap;
	Mat frame;

	string videoStreamAddress = "rtmp://192.168.254.104:1935/live/live";
	if (!vcap.open(videoStreamAddress)) {
		cout << "Error opening video stream or file" << endl;
		return;
	}

	while (true) {
		vcap.read(frame);
		if (frame.empty()) {
			cout << "frame empty" << endl;
			break;
		}
		flip(frame, frame, 1);//视频图像左右翻转
		imshow("RTMP", frame);

		int c = waitKey(10);
		if (c == 27) {
			break;
		}

	}
	//release 释放摄像头资源
	vcap.release();
}

//图像直方图
void QuickDemo::histogram_Demo(Mat &image)
{
	//三通道分离
	vector<Mat> bgr_plane;
	split(image, bgr_plane);

	//定义参数变量
	const int channels[1] = { 0 };
	const int bins[1] = { 256 };
	float hranges[2] = { 0,255 };
	const float * ranges[1] = { hranges };
	Mat b_hist;
	Mat g_hist;
	Mat r_hist;

	//计算Blue,Green,Red通道的直方图
	calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges);
	calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, bins, ranges);
	calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, bins, ranges);

	//定义直方图窗口
	int hist_w = 512;
	int hist_h = 400;
	int bin_w = cvRound((double)hist_w / bins[0]);
	Mat histImage = Mat::zeros(Size(hist_w, hist_h), CV_8UC3);

	//归一化直方图数据
	normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
	normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
	normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());

	//绘制直方图曲线
	for (int i = 1; i < bins[0]; i++) {
		line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
			Point(bin_w*(i), hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, 8, 0);
		line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
			Point(bin_w*(i), hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, 8, 0);
		line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
			Point(bin_w*(i), hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, 8, 0);
	}

	//显示直方图
	namedWindow("Histogrma Demo", WINDOW_AUTOSIZE);
	imshow("Histogrma Demo", histImage);
}

//二维直方图
void QuickDemo::histogram2d_Demo(Mat &image)
{
	//2D直方图
	Mat hsv, hs_hist;
	cvtColor(image, hsv, COLOR_RGB2HSV);//转成HSV图像
	int hbins = 30, sbins = 32;//划分比例 180/30=5 256/32=8
	int hist_bins[] = { hbins,sbins };
	float h_range[] = { 0,180 };//H范围
	float s_range[] = { 0,256 };//S范围
	const float* hs_ranges[] = { h_range,s_range };//范围指针的指针
	int hs_channels[] = { 0,1 };//通道数
	calcHist(&hsv, 1, hs_channels, Mat(), hs_hist, 2, hist_bins, hs_ranges);//二维直方图转换
	double maxVal = 0;
	minMaxLoc(hs_hist, 0, &maxVal, 0, 0);
	int scale = 10;
	//定义2D直方图窗口
	Mat hist2d_image = Mat::zeros(sbins*scale, hbins*scale, CV_8UC3);
	for (int h = 0; h < hbins; h++) {
		for (int s = 0; s < sbins; s++) {
			float binVal = hs_hist.at<float>(h, s);
			//占比数量
			int intensity = cvRound(binVal * 255 / maxVal);
			//画矩形
			rectangle(hist2d_image, Point(h*scale, s*scale),
				Point((h + 1)*scale - 1, (s + 1)*scale - 1),
				Scalar::all(intensity),
				-1);
		}
	}
	//图像颜色转换
	applyColorMap(hist2d_image, hist2d_image, COLORMAP_JET);
	imshow("H-S Histogram", hist2d_image);
	imwrite("./Image/hist_2d.png", hist2d_image);
}

//直方图均衡化
void QuickDemo::histogramEq_Demo(Mat &image)
{
	Mat gray;
	cvtColor(image, gray, COLOR_RGB2GRAY);
	imshow("灰度图像", gray);
	Mat dst;
	equalizeHist(gray, dst);
	imshow("直方图均衡化演示", dst);

	//彩色图像直方图均衡化
	//Mat hsv;
	//cvtColor(image, hsv, COLOR_RGB2HSV);
	//vector<Mat> hsvVec;
	//split(hsv, hsvVec);
	//equalizeHist(hsvVec[2], hsvVec[2]);
	//Mat hsvTmp;
	//merge(hsvVec, hsvTmp);
	//Mat dst;
	//cvtColor(hsvTmp, dst, COLOR_HSV2RGB);
	//imshow("直方图均衡化演示", dst);
}

//图像卷积操作(模糊)
void QuickDemo::blur_Demo(Mat &image)
{
	Mat dst;
	blur(image, dst, Size(13, 13), Point(-1, -1));
	imshow("图像模糊", dst);
}
//高斯模糊
void QuickDemo::gaussianBlur_Demo(Mat &image)
{
	Mat dst;
	GaussianBlur(image, dst, Size(7, 7), 15);
	imshow("高斯模糊", dst);
}

//高斯双边模糊
void QuickDemo::bifilter_Demo(Mat &image)
{
	Mat dst;
	bilateralFilter(image, dst, 0, 100, 10);
	imshow("高斯双边模糊", dst);
}

//实时人脸检测
void QuickDemo::faceDetection_Demo(Mat &image)
{
	string root_dir = "D:/opencv4.5.0/opencv/sources/samples/dnn/face_detector/";
	Net net = readNetFromTensorflow(root_dir + "opencv_face_detector_uint8.pb", root_dir + "opencv_face_detector.pbtxt");
	VideoCapture capture(0);
	//VideoCapture capture;
	//string videoStreamAddress = "rtmp://192.168.254.104:1935/live/live";
	//if (!capture.open(videoStreamAddress)) {
	//	cout << "Error opening video stream or file" << endl;
	//	return;
	//}

	Mat frame;

	while (true) {
		capture.read(frame);
		if (frame.empty()) {
			cout << "frame empty" << endl;
			break;
		}
		flip(frame, frame, 1);//视频图像左右翻转
		Mat blob = blobFromImage(frame, 1.0, Size(300, 300), Scalar(104, 177, 123), false, false);
		net.setInput(blob);//NCHW
		Mat probs = net.forward();
		Mat detectionMat(probs.size[2], probs.size[3], CV_32F, probs.ptr<float>());

		//解析结果
		int num = 0;
		float confidence = 0.0;
		float fTemp = 0.0;
		for (int i = 0; i < detectionMat.rows; i++) {
			confidence = detectionMat.at<float>(i, 2);
			if (confidence > 0.5) {
				fTemp = confidence;
				int x1 = static_cast<int>(detectionMat.at<float>(i, 3)*frame.cols);
				int y1 = static_cast<int>(detectionMat.at<float>(i, 4)*frame.cols);
				int x2 = static_cast<int>(detectionMat.at<float>(i, 5)*frame.cols);
				int y2 = static_cast<int>(detectionMat.at<float>(i, 6)*frame.cols);
				Rect box(x1, y1, x2 - x1, y2 - y1);
				rectangle(frame, box, Scalar(0, 0, 255), 2, 8, 0);

				num++;
			}
		}
		//Mat dst;
		//bilateralFilter(frame, dst, 0, 100, 10);//高斯双边模糊

		putText(frame, "NO." + to_string(num) + " SSIM:"+ to_string(fTemp), Point(30, 50), FONT_HERSHEY_TRIPLEX, 1.3, Scalar(26, 28, 124), 4);

		imshow("人脸实时检测", frame);
		int c = waitKey(1);
		if (c == 27) {
			break;
		}
	}
}

//人脸照片检测
//void QuickDemo::faceDetection_Demo(Mat &image)
//{
//	string root_dir = "D:/opencv4.5.0/opencv/sources/samples/dnn/face_detector/";
//	Net net = readNetFromTensorflow(root_dir + "opencv_face_detector_uint8.pb", root_dir + "opencv_face_detector.pbtxt");
//
//	Mat frame;
//	frame = image.clone();
//
//	while (true) {
//		frame = image.clone();
//		//flip(frame, frame, 1);//视频图像左右翻转
//		Mat blob = blobFromImage(frame, 1.0, Size(300, 300), Scalar(104, 177, 123), false, false);
//		net.setInput(blob);//NCHW
//		Mat probs = net.forward();
//		Mat detectionMat(probs.size[2], probs.size[3], CV_32F, probs.ptr<float>());
//
//		//解析结果
//		int num = 0;
//		
//		for (int i = 0; i < detectionMat.rows; i++) {
//			float confidence = detectionMat.at<float>(i, 2);
//			if (confidence > 0.5) {
//				int x1 = static_cast<int>(detectionMat.at<float>(i, 3)*frame.cols);
//				int y1 = static_cast<int>(detectionMat.at<float>(i, 4)*frame.cols);
//				int x2 = static_cast<int>(detectionMat.at<float>(i, 5)*frame.cols);
//				int y2 = static_cast<int>(detectionMat.at<float>(i, 6)*frame.cols);
//				Rect box(x1, y1, x2 - x1, y2 - y1);
//				rectangle(frame, box, Scalar(0, 0, 255), 2, 8, 0);
//
//				num++;
//			}
//		}
//
//		putText(frame, "NO." + to_string(num) + " pcs", Point(30, 50), FONT_HERSHEY_TRIPLEX, 1.3, Scalar(124, 28, 26), 2);
//
//		imshow("人脸实时检测", frame);
//
//		int c = waitKey(1000);
//		if (c == 27) {
//			break;
//		}
//	}
//}

 

2.3 测试代码 test450.cpp

//test450.cpp

#include <opencv2/opencv.hpp>
#include <iostream>
#include "QuickDemo.h"

using namespace cv;
using namespace std;

int main()
{
	//Mat src = imread("./Image/girl.jpg"); 
	//Mat src = imread("./Image/example.png");
	Mat src = imread("./Image/persons.jpg"); 
	if (src.empty()){
		printf("could not load image...\n");
		cout << "could not load image..." << endl;
		return -1;
	}

	//Mat gray = src.clone();
	//cvtColor(gray, src, COLOR_RGB2GRAY);

	imshow("输入窗口", src);

	QuickDemo qd;
	qd.faceDetection_Demo(src);

	waitKey(0);
	destroyAllWindows();
	return 0;
}

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【OpenCV】C++ OpenCV 快速入门案例Demo 的相关文章

随机推荐