Opencv图像处理代码

#include "head.h"
void Person::showImg(Mat &img) 
{
	namedWindow("透明通道显示白色背景", WINDOW_NORMAL);
	if (img.empty())
	{
		cout << "图片路径错误" << endl;
		return ;
	}
	imshow("透明通道显示白色背景", img);
	imwrite("D:/opencvSourse/openImg/保存的图片/透明通道.png", img);
}

void Person::creatMat(Mat& img)
{
	//creatOne
	Mat colorImg = Mat(255, 255, CV_8UC3);
	imshow("1", colorImg);

	//creatTow
	Mat cImg = Mat(Size(img.size()), img.type());
	imshow("2", colorImg);

	//深拷贝
	Mat img1 = img.clone();
	imshow("深拷贝1", img1);
	Mat img2;
	img.copyTo(img2);
	imshow("深拷贝2", img2);
}

void Person::ergodic(Mat& img)
{
	imshow("原始", img);
	int dis = img.channels();
	for (int row = 0; row < img.rows; row++)
	{
		for (int col = 0; col < img.cols; col++)
		{
			if (dis == 1)
			{
				img.at<uchar>(row, col) = 255 - img.at<uchar>(row, col);
			}
			if (dis == 3)
			{
				Vec3b vec = img.at<Vec3b>(row, col);
				img.at<Vec3b>(row, col)[0] = 255 - vec[0];
				img.at<Vec3b>(row, col)[1] = 255 - vec[1];
				img.at<Vec3b>(row, col)[2] = 255 - vec[2];
			}
		}
	}
	imshow("转换", img);
}

void Person::homeErgodic(Mat& img)
{
	imshow("原始", img);
	int dis = img.channels();
	for (int row = 0; row < img.rows; row++)
	{
		uchar* p = img.ptr<uchar>(row);
		if (dis == 1)
		{
			for (int col = 0; col < img.cols; col++)
			{
				*p = 255 - *p;
			}
		}
		for (int col = 0; col < img.cols; col++)
		{
			*p++ = 255 - *p;
			*p++ = 255 - *p;
			*p++ = 255 - *p;
		}
	}
	imshow("转换", img);
}

void Person::arithmetic()
{
	Mat img1 = imread("D:/opencvDownLoad/opencv-4.5.1/opencv/sources/samples/data/WindowsLogo.jpg");
	Mat img2 = imread("D:/opencvDownLoad/opencv-4.5.1/opencv/sources/samples/data/LinuxLogo.jpg");
	Mat dst;
	add(img1, img2, dst);
	imshow("add", dst);
	subtract(img1, img2, dst);
	imshow("subtract", dst);
	multiply(img1, img2, dst);
	imshow("multiply", dst);
	divide(img1, img2, dst);
	imshow("divide", dst);
}

void trackbarFn(int min, void *img)
{
	Mat newImg = *(Mat*)img;
	Mat src = Mat::zeros(newImg.size(), newImg.type());
	Mat dst;
	addWeighted(newImg, 1.0, src, 0, min, dst);
	imshow("调节", dst);
}
void trackbarFn1(int min, void* img)
{
	Mat newImg = *(Mat*)img;
	Mat src = Mat::zeros(newImg.size(), newImg.type());
	Mat dst;
	double newMin = min / 100.0;
	addWeighted(newImg, newMin, src, 0, 1, dst);
	imshow("调节", dst);
}
void Person::myTrackBar(Mat &img)
{
	
	namedWindow("调节");
	imshow("调节", img);
	string barName = "亮度调节";
	string barName1 = "对比度调节";
	string windName = "调节";
	int min = 20;
	int max = 200;
	createTrackbar(barName, windName, &min, max, trackbarFn, (void*)&img);
	createTrackbar(barName1, windName, &min, max, trackbarFn1, (void*)&img);
}

void Person::logic(Mat &img)
{
	imshow("原图", img);
	Mat mask = Mat::zeros(img.size(), CV_8UC1);
	Mat dst;
	double width = img.rows;
	double height = img.cols;
	for (int cols = 100; cols < height / 2; cols++)
	{
		uchar*p = mask.ptr<uchar>(cols);
		for (int rows = 200; rows < width / 2; rows++)
		{
			*p++ = 255;
		}
	}
	imshow("mask", mask);
	bitwise_not(img, dst, mask);
	imshow("取反", dst);
}

void Person::varianceAverage(Mat& img)
{
	Mat newImg = Mat::zeros(Size(255, 255), CV_8UC3);
	newImg = Scalar(0, 0, 255);
	vector<Mat> vec;
	split(newImg, vec);
	double min; double max; Point minloc; Point maxloc;
	for (int channels = 0; channels < vec.size(); channels++)
	{
		minMaxLoc(vec[channels], &min, &max, &minloc, &maxloc);
		cout << "最小值: " << min << "\t" << "最大值: " << max << "\t"
			<< "最小值x: " << minloc.x << "\t" << "最小值y: " << minloc.y << endl;
	}
	Mat mean; Mat stdDev;
	for (int channels = 0; channels < vec.size(); channels++)
	{
		meanStdDev(vec[channels], mean, stdDev);
		cout << "通道: " << channels << " 均值: " << mean << "\t"
			<< "方差: " << stdDev << endl;
	}
}

void Person::draw()
{
	Mat canvas = Mat::zeros(Size(500, 500), CV_8UC3);
	line(canvas, Point(0, 0), Point(500, 500), Scalar(150, 120, 180), 2, LINE_AA);
	rectangle(canvas, Rect(10, 200, 300, 300), Scalar(0, 0, 200), -1, 8);
	circle(canvas, Point(250, 250), 100, Scalar(200, 10, 10), -1, 8);
	ellipse(canvas, RotatedRect(Point(300, 100), Size(200, 100), 45.5), Scalar(0, 200, 10), -1, LINE_AA);
	imshow("convas", canvas);
	Mat rngImg = Mat::zeros(Size(500, 500), CV_8UC3);
	RNG rng(12345);
	while (true)
	{
		int x = rng.uniform(0, 500); int y = rng.uniform(0, 500);
		int x1 = rng.uniform(0, 500); int y1 = rng.uniform(0, 500);
		line(rngImg, Point(x, y), Point(x1, y1), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);
		imshow("rng", rngImg);

		int key = waitKey(100);
		rngImg = Scalar(0, 0, 0);
		if (key == 27)
		{
			break;
		}
	}
}

void Person::splitMerge(Mat& img)
{
	imshow("原图", img);
	vector<Mat> vec;
	split(img, vec);
	vec[0] = 0;
	Mat dst;
	merge(vec, dst);
	imshow("dst", dst);
	cout << img.cols << "高" << img.rows;
	Rect roi = Rect(100, 50, 300, 300);
	//浅拷贝ROI
	Mat roiImg = img(roi);
	//深拷贝ROI
	//Mat roiImg = img(roi).clone();
	imshow("ROI", roiImg);
	imshow("浅拷贝", img);
}

//直方图
//void Person::histogram(Mat& img)
//{
//	imshow("原图", img);
//	vector<Mat> vec;
//	split(img, vec);
//	Mat bImg; Mat gImg; Mat rImg;
//	//竖条个数
//	int bins = 256;
//	//范围
//	float rangs[] = {0,255};
//	//多个通道rangs
//	const float* rangsChannels = { rangs };
//	//直方图
//	calcHist(&vec[0], 1, 0, Mat(), bImg, 1, &bins, &rangsChannels, true, false);
//	calcHist(&vec[1], 1, 0, Mat(), gImg, 1, &bins, &rangsChannels, true, false);
//	calcHist(&vec[2], 1, 0, Mat(), rImg, 1, &bins, &rangsChannels, true, false);
//
//	//归一化
//	Mat dst = Mat::zeros(Size(600, 500), CV_8UC3);
//	int margin = 50;
//	int dH = dst.rows - 2 * margin;
//	normalize(bImg, bImg, 0, dH, NORM_MINMAX, -1, Mat());
//	normalize(gImg, gImg, 0, dH, NORM_MINMAX, -1, Mat());
//	normalize(rImg, rImg, 0, dH, NORM_MINMAX, -1, Mat());
//
//	//把直方图放到归一化的img
//
//	//求bins
//	float xStep = (dst.cols - 2 * margin) / 256.0;
//	cout << xStep << endl;
//	//i最大值为256, 但是后面i++, so: i = 255
//	for (int i = 0; i < 255; i++)
//	{
//		//求dims
//		//float dims = bImg.at<float>(i, 0);
//		//line p1
//	/*	Point p1 = Point(xStep * i, margin+(dst.rows - dims) );
//		dims = dst.at<float>(i+1, 0);
//		Point p2 = Point(xStep * i, margin + (dst.rows - dims) );*/
//
//
//		//line(dst, p1, p2,Scalar(255,0,0),2,8);
//		line(dst, Point(xStep * i + margin, margin + (dH - bImg.at<float>(i, 0))), Point(xStep * (i + 1) + margin, margin + (dH - bImg.at<float>(i + 1, 0))), Scalar(255, 0, 0),2,8,0);
//		line(dst, Point(xStep * i + margin, margin + (dH - gImg.at<float>(i, 0))), Point(xStep * (i + 1) + margin, margin + (dH - gImg.at<float>(i + 1, 0))), Scalar(0, 255, 0),2,8,0);
//		line(dst, Point(xStep * i + margin, margin + (dH - rImg.at<float>(i, 0))), Point(xStep * (i + 1) + margin, margin + (dH - rImg.at<float>(i + 1, 0))), Scalar(0, 0, 255),2,8,0);
//	}
//	imshow("直方图", dst);
//}

void Person::histogram(Mat& img)
{
	imshow("原始", img);
	int bins = 256;
	float rangs[] = { 0,255 };
	const float* everyRangs = { rangs };
	vector<Mat> vec;
	split(img, vec);
	Mat bImg; Mat gImg; Mat rImg;
	calcHist(&vec[0], 1, 0, Mat(), bImg, 1, &bins, &everyRangs, true, false);
	calcHist(&vec[1], 1, 0, Mat(), gImg, 1, &bins, &everyRangs, true, false);
	calcHist(&vec[2], 1, 0, Mat(), rImg, 1, &bins, &everyRangs, true, false);
	Mat dst = Mat::zeros(Size(600, 400), img.type());
	float margin = 50;
	float height = dst.rows - 2 * 50;
	float xStep = (dst.cols - 2 * margin) / float(bins);
	cout << "步长" << xStep << endl;
	cout << "高度" << height << endl;
	normalize(bImg, bImg, 0, height, NORM_MINMAX, -1, Mat());
	normalize(gImg, gImg, 0, height, NORM_MINMAX, -1, Mat());
	normalize(rImg, rImg, 0, height, NORM_MINMAX, -1, Mat());
	for (int i = 0; i < bins-1; i++)
	{
		line(dst, Point(i * xStep + margin, margin + (height - bImg.at<float>(i, 0))), Point((i + 1) * xStep + margin, margin + (height - bImg.at<float>((i + 1) , 0))), Scalar(255, 0, 0), 2, 8, 0);
		line(dst, Point(i * xStep + margin, margin + (height - gImg.at<float>(i, 0))), Point((i + 1) * xStep + margin, margin + (height - gImg.at<float>((i + 1) , 0))), Scalar(0, 255, 0), 2, 8, 0);
		line(dst, Point(i * xStep + margin, margin + (height - rImg.at<float>(i, 0))), Point((i + 1) * xStep + margin, margin + (height - rImg.at<float>((i + 1) , 0))), Scalar(0, 0, 255), 2, 8, 0);
	}
	imshow("归一化", dst);
}

//直方图均衡化

void Person::myEqualizeHist(Mat& img)
{
	cvtColor(img, img, COLOR_BGR2GRAY);
	imshow("灰色", img);
	Mat equImg;
	equalizeHist(img, equImg);
	Mat src; Mat dst;
	int bins = 256;
	float rang[] = { 0,255 };
	const float* rangs = { rang };
	calcHist(&img, 1, 0, Mat(), src, 1, &bins, &rangs, true, false);
	calcHist(&equImg, 1, 0, Mat(), dst, 1, &bins, &rangs, true, false);
	Mat outImg = Mat::zeros(Size(600, 400), CV_8UC3);
	int margin = 50;
	float Hight = float(outImg.rows) - float(2 * margin);
	float step = (outImg.cols - 2 * margin) / float(bins);
	cout << Hight << "\t" << step << endl;
	normalize(src, src, 0, Hight, NORM_MINMAX, -1, Mat());
	normalize(dst, dst, 0, Hight, NORM_MINMAX, -1, Mat());
	for (int i = 0; i < bins - 1; i++)
	{
		line(outImg, Point(step * i + margin, margin + (Hight - src.at<float>(i, 0))), Point(step * (i + 1) + margin, margin + (Hight - src.at<float>(i + 1, 0))), Scalar(0, 0, 255), 2, 8, 0);
		line(outImg, Point(step * i + margin, margin + (Hight - dst.at<float>(i, 0))), Point(step * (i + 1) + margin, margin + (Hight - dst.at<float>(i + 1, 0))), Scalar(0, 255, 255), 2, 8, 0);
	}
	imshow("结果", outImg);
}

//直方图比较
void Person::histCompare(Mat& img, Mat& img1)
{
	Mat dst; Mat dst1;
	int bins[] = { 200,200,200 };
	float rang[] = { 0,255 };
	const float* rangs[] = { rang,rang,rang };
	int channls[] = { 0,1,2 };
	calcHist(&img, 1, channls, Mat(), dst, img.channels(), bins, rangs, true, false);
	calcHist(&img1, 1, channls, Mat(), dst1, img.channels(), bins, rangs, true, false);

	normalize(dst, dst, 0, 1, NORM_MINMAX, -1, Mat());
	normalize(dst1, dst1, 0, 1, NORM_MINMAX, -1, Mat());

	float result1 = compareHist(dst, dst1, HISTCMP_BHATTACHARYYA); // 越大越不像
	float resemble = compareHist(dst, dst, HISTCMP_BHATTACHARYYA);
	cout << "巴氏距离" << result1 << "\t" << resemble << endl;
	float result2 = compareHist(dst, dst1, HISTCMP_CORREL);
	float resemble1 = compareHist(dst, dst, HISTCMP_CORREL);
	cout << "相似性" << result2 << "\t" << resemble1 << endl;
}

void Person::colormap(Mat& img)
{
	imshow("原始", img);
	Mat dst;
	applyColorMap(img, dst, COLORMAP_AUTUMN);
	imshow("颜色表", dst);
}

void Person::myblur(Mat& img)
{
	imshow("img", img);
	float width = img.cols;
	float height = img.rows;
	Mat dst = img.clone(); Mat dst1 = img.clone();
	float b_value; float g_value; float r_value;
	for (int h = 1; h < height - 1; h++)
	{
		for (int w = 1; w < width - 1; w++)
		{
			dst.at<Vec3b>(h, w)[0] = (img.at<Vec3b>(h - 1, w - 1)[0] + img.at<Vec3b>(h - 1, w)[0] + img.at<Vec3b>(h - 1, w + 1)[0] +
				img.at<Vec3b>(h, w - 1)[0] + img.at<Vec3b>(h, w)[0] + img.at<Vec3b>(h, w + 1)[0] +
				img.at<Vec3b>(h + 1, w - 1)[0] + img.at<Vec3b>(h + 1, w)[0] + img.at<Vec3b>(h + 1, w + 1)[0])
				/ 9;

			dst.at<Vec3b>(h, w)[1] = (img.at<Vec3b>(h - 1, w - 1)[1] + img.at<Vec3b>(h - 1, w)[1] + img.at<Vec3b>(h - 1, w + 1)[1] +
				img.at<Vec3b>(h, w - 1)[1] + img.at<Vec3b>(h, w)[1] + img.at<Vec3b>(h, w + 1)[1] +
				img.at<Vec3b>(h + 1, w - 1)[1] + img.at<Vec3b>(h + 1, w)[1] + img.at<Vec3b>(h + 1, w + 1)[1]) / 9;

			dst.at<Vec3b>(h, w)[2] = (img.at<Vec3b>(h - 1, w - 1)[2] + img.at<Vec3b>(h - 1, w)[2] + img.at<Vec3b>(h - 1, w + 1)[2] +
				img.at<Vec3b>(h, w - 1)[2] + img.at<Vec3b>(h, w)[2] + img.at<Vec3b>(h, w + 1)[2] +
				img.at<Vec3b>(h + 1, w - 1)[2] + img.at<Vec3b>(h + 1, w)[2] + img.at<Vec3b>(h + 1, w + 1)[2]) / 9;
		}
	}
	imshow("myBlur", dst);
	blur(img, dst1, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
	imshow("API", dst1);
}

void Person::borderBlur(Mat& img)
{
	imshow("ipt", img);
	Mat dst;
	float margin = 9;
	//copyMakeBorder(img, dst, margin, margin, margin, margin, BORDER_DEFAULT);
	copyMakeBorder(img, dst, margin, margin, margin, margin, BORDER_CONSTANT,Scalar(0,0,200));
	imshow("卷积", dst);
}

void Person::GauBox(Mat& img)
{
	imshow("ipt", img);
	Mat dst; Mat dst1;
	boxFilter(img, dst, -1, Size(5, 5), Point(-2, -2), true, BORDER_DEFAULT);
	GaussianBlur(img, dst1, Size(5, 5), BORDER_DEFAULT);
	imshow("高斯模糊", dst1);
	imshow("盒子模糊", dst);
}

void Person::customFilter(Mat& img)
{
	imshow("原图", img);
	//自定义均值卷积
	Mat dst;
	int width = 15;
	int height = 15;
	//归一化
	Mat kernel = Mat::ones(width, height, CV_32F) / float(width * height);
	filter2D(img, dst, -1, kernel, Point(-1, -1), 0, BORDER_DEFAULT);
	imshow("自定义均值滤波", dst);

	//自定义高斯卷积
	Mat dst1;
	int gWidth = 2;
	int gHeight = 2;
	/*Mat kernel1 = (Mat_<int>(gWidth, gHeight) << 1, 0, 0, 0, 1, 0, 0, 0, -1);*/
	Mat kernel1 = (Mat_<int>(gWidth, gHeight) << 1, 0, 0,-1);
	filter2D(img, dst1, CV_32F, kernel1, Point(-1, -1), 200, BORDER_DEFAULT);
	convertScaleAbs(dst1, dst1);
	imshow("非均值滤波", dst1);

}

void Person::myRobot(Mat& img)
{
	//robot
	imshow("原图", img);
	Mat xKernel = (Mat_<int>(2, 2) << 1, 0, 0, -1);
	Mat yKernel = (Mat_<int>(2, 2) << 0, 1, -1, 0);
	Mat xImg; Mat yImg; Mat dst; Mat dst1; Mat dst2;
	filter2D(img, xImg, CV_32F, xKernel, Point(-1, -1), 0, BORDER_DEFAULT);
	filter2D(img, yImg, CV_32F, yKernel, Point(-1, -1), 0, BORDER_DEFAULT);
	convertScaleAbs(xImg, xImg);
	convertScaleAbs(yImg, yImg);
	dst = xImg + yImg;
	imshow("robot", dst);

	//sobel
	Sobel(img, xImg, CV_32F, 1, 0);
	Sobel(img, yImg, CV_32F, 1, 0);
	convertScaleAbs(xImg, xImg);
	convertScaleAbs(yImg, yImg);
	addWeighted(xImg, 0.5, yImg, 0.5, 0, dst1);
	imshow("sobel", dst1);

	//scharr
	Scharr(img, xImg, CV_32F, 1, 0);
	Scharr(img, yImg, CV_32F, 1, 0);
	convertScaleAbs(xImg, xImg);
	convertScaleAbs(yImg, yImg);
	addWeighted(xImg, 0.5, yImg, 0.5, 0, dst1);
	imshow("scharr", dst1);
}

void Person::myLaplacian(Mat& img)
{
	imshow("原图", img);
	Mat dst; Mat dst1;
	Laplacian(img, dst, -1, 3, 1, 123, BORDER_DEFAULT);
	imshow("拉普拉斯", dst);

	//图像锐化 = 拉普拉斯+img本身
	Mat kernel = (Mat_<int>(3,3)<<0, -1, 0,
								 -1, 5, -1,
								  0, -1, 0);
	filter2D(img, dst1, CV_32F, kernel, Point(-1, -1), 0, BORDER_DEFAULT);
	convertScaleAbs(dst1, dst1);
	imshow("锐化", dst1);
}

void Person::sum(Mat& img)
{
	//blur - lapla
	imshow("原图", img);
	Mat gaussImg; Mat laplaImg; Mat sumImg;
	GaussianBlur(img, gaussImg, Size(3, 3), 0);
	Laplacian(img, laplaImg, -1, 3,1.0,0,BORDER_DEFAULT);

	addWeighted(gaussImg, 1.0, laplaImg, -0.7, 0, sumImg);
	imshow("sum锐化", sumImg);
}

void Person::noise(Mat& img)
{
	imshow("原图", img);
	//椒盐噪声
	Mat saltPepper = img.clone();
	RNG rng(123456);
	int width = img.cols;
	int height = img.rows;
	int number = 10000;
	for (int i = 0; i < number; i++) {
		int x = rng.uniform(0, width);
		int y = rng.uniform(0, height);
		if (i % 2)
		{
			saltPepper.at<Vec3b>(x, y) = Vec3b(255, 255, 255) ;
		}
		else
		{
			saltPepper.at<Vec3b>(x, y) = Vec3b(0, 0, 0) ;
		}
	}
	imshow("椒盐噪声", saltPepper);

	//高斯噪声
	Mat dst;
	Mat randnImg = Mat::zeros(img.size(), img.type());
	randn(randnImg, Scalar(20, 30, 40), Scalar(10, 15, 20));
	imshow("高斯原图", randnImg);
	add(img, randnImg, dst);
	imshow("高斯噪声", dst);

	Mat dst1; Mat dst2; Mat dst3;
	//利用中值去除椒盐噪声
	medianBlur(saltPepper, dst1, 3);
	imshow("中值去噪", dst1);

	//均值去噪
	GaussianBlur(dst, dst2, Size(3, 3), 0);
	medianBlur(dst, dst3, 3);
	imshow("高斯去噪", dst2);
	imshow("中值去噪高斯", dst3);
}

void Person::cleanNoise(Mat& img)
{
	Mat dst; Mat dst1;
	imshow("原图", img);
	//双边模糊去噪
	bilateralFilter(img, dst, 10, 100, 10);
	imshow("高斯去噪", dst);

	//非局部均值滤波
	fastNlMeansDenoising(img, dst1, 10, 7, 21);
	imshow("非局部均值去噪", dst1);
}

void myCanny(int min, void* img)
{
	Mat newImg = *(Mat*)img;
	Mat dst; Mat dst1;
	Canny(newImg, dst, min, 200, 3, false);
	bitwise_and(newImg, newImg, dst1, dst);
	imshow("边缘提取", dst1);
}
void Person::canny(Mat& img)
{
	string barName = "提取范围";
	string winName = "边缘提取";
	namedWindow(winName, WINDOW_AUTOSIZE);
	imshow("原图", img);
	int min = 50;
	int max = 220;
	createTrackbar(barName, winName, &min, max, myCanny,(void*)&img);
	myCanny(0, (void*)&img);
}

//二值化分割
void Person::myThreshold(Mat& img)
{
	Mat dst;
	cvtColor(img, img, COLOR_BGR2GRAY);
	imshow("原图灰色图像", img);
	//二值化
	threshold(img, dst, 127, 255, THRESH_BINARY);
	imshow("二值化", dst);
	//反二值化
	threshold(img, dst, 127, 255, THRESH_BINARY_INV);
	imshow("反二值化", dst);
	//阈值化切割, 小于阈值化保持原数据, 否则为T
	threshold(img, dst, 127, 255, THRESH_TRUNC);
	imshow("阈值化切割", dst);
	//阈值化,大于T的保持原数据, 其他的为0
	threshold(img, dst, 127, 255, THRESH_TOZERO);
	imshow("阈值化", dst);
	//反阈值化, 
	threshold(img, dst, 127, 255, THRESH_TOZERO_INV);
	imshow("反阈值化", dst);
}
//返回二值化分割
Mat Person::myThresh(const Mat& img)
{
	Mat newImg = img.clone();
	GaussianBlur(newImg, newImg, Size(3, 3), 0);
	cvtColor(newImg, newImg, COLOR_BGR2GRAY);
	Mat dst;
	threshold(newImg, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
	return dst;
}


//全局求阈值分割
void Person::tThreshold(Mat& img)
{
	Mat dst;
	cvtColor(img, img, COLOR_BGR2GRAY);
	imshow("原图", img);
	Scalar m = mean(img);
	threshold(img, dst, m[0], 255, THRESH_BINARY);
	imshow("均值", dst);
	//otsu
	double otsu = threshold(img, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("otsu", dst);
	//三角法
	double angle = threshold(img, dst, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
	imshow("三角法", dst);
	cout << "otsu切割阈值T: " << otsu << "\t" << "三角法: " << angle << endl
		<<"\t" << "均值:"<<m[0];
}

//自适应阈值分割
void Person::myAdaptive(Mat &img)
{
	Mat dst;
	cvtColor(img, img, COLOR_BGR2GRAY);
	imshow("原图", img);
	threshold(img, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("otsu", dst);
	//自适应
	adaptiveThreshold(img, dst, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 21, 5);
	imshow("自适应", dst);
}

//联通组件
void Person::connectComp(Mat& img)
{
	RNG rn(12345);
	imshow("原图", img);
	Mat denoi;
	GaussianBlur(img, denoi, Size(11, 11), 0);
	imshow("去噪", denoi);
	Mat grey;
	cvtColor(denoi, grey, COLOR_BGR2GRAY);
	Mat cutting;
	threshold(grey, cutting, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("二值化", cutting);
	Mat labels = Mat::zeros(img.size(), CV_32S);
	int num = connectedComponents(cutting, labels, 8, CV_32S, CCL_DEFAULT);
	cout << "数量" << num << endl;
	//染色
	vector<Vec3b>color(num);
	color[0] = Vec3b(0, 0, 0);
	for (int index = 1; index < num; index++)
	{
		color[index] = Vec3b(rn.uniform(0, 256), rn.uniform(0, 256), rn.uniform(0, 256));
	}
	Mat result = Mat::zeros(img.size(), CV_8UC3);
	for (int x = 0; x < result.rows; x++)
	{
		for (int y = 0; y < result.cols; y++)
		{
			result.at<Vec3b>(x, y) = color[labels.at<int>(x, y)];
		}
	}
	//显示详细信息
	Mat stats; Mat centroids;
	int num1 = connectedComponentsWithStats(cutting, labels, stats, centroids, 8, CV_32S, CCL_DEFAULT);
	string numn = to_string(num1);
	for (int i = 1; i < num1; i++)
	{
		//center
		double centerX = centroids.at<double>(i, 0);
		double centerY = centroids.at<double>(i, 1);
		//ractangle
		int racLeft = stats.at<int>(i, CC_STAT_LEFT);
		int racTop = stats.at<int>(i, CC_STAT_TOP);
		int racWidth = stats.at<int>(i, CC_STAT_WIDTH);
		int racHeight = stats.at<int>(i, CC_STAT_HEIGHT);
		int area = stats.at<int>(i, CC_STAT_AREA);
		cout << "面积" << i << area << endl;
		string s =  to_string(area);
		circle(result, Point(centerX, centerY), 3, Scalar(255, 20, 20), 2, 8);
		Rect rect = Rect(racLeft, racTop, racWidth, racHeight);
		rectangle(result, rect, Scalar(0, 0, 200), 2, LINE_8);
		putText(result, s, Point(centerX, centerY), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 2, 8);
		putText(result, numn, Point(50,50), FONT_HERSHEY_PLAIN, 3, Scalar(0, 255, 0), 2, 8);
	}
	imshow("切割染色", result);
}
//void Person::connectComp(Mat& img)
//{
//	RNG rng(12345);
//	imshow("ipt", img);
//	GaussianBlur(img, img, Size(3, 3), 0);
//	Mat gray; Mat binary;
//	cvtColor(img, gray, COLOR_BGR2GRAY);
//	threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
//	imshow("二值化", binary);
//	Mat lables = Mat::zeros(binary.size(), CV_32S);
//	int num = connectedComponents(binary, lables, 8, CV_32S, CCL_DEFAULT);
//	vector<Vec3b>vec(num);
//	vec[0] = Vec3b(0, 0, 0);
//	for (int i = 0; i < num; i++)
//	{
//		vec[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
//	}
//	Mat result = Mat::zeros(img.size(), img.type());
//	for (int x = 0; x < result.rows; x++)
//	{
//		for (int y = 0; y < result.cols; y++)
//		{
//			int lab = lables.at<int>(x, y);
//			result.at<Vec3b>(x, y) = vec[lab];
//		}
//	}
//	imshow("颜色表", result);
//}

//轮廓提取
void Person::myContour(Mat& img)
{
	Mat binaryImg = this->myThresh(img).clone();
	Mat dst = Mat::zeros(img.size(),CV_8UC3);
	Mat dst1 = dst.clone();
	Mat dst2 = dst.clone();
	imshow("二值化", binaryImg);
	vector<vector<Point>>contours;
	vector<Vec4i>hierarchy;
	findContours(binaryImg, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
	for (int i = 0; i < contours.size(); i++)
	{
		drawContours(dst, contours, i, Scalar(0, 255, 0), 2, LINE_8);
	}
	imshow("轮廓", dst);
	findContours(binaryImg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	drawContours(dst1, contours, -1, Scalar(255, 0, 0), 2, 8);
	imshow("最大轮廓", dst1);
}

//轮廓细节
void Person::contourDetails(Mat& img)
{
	Mat result = Mat::zeros(img.size(), CV_8UC3);
	imshow("原图", img);
	GaussianBlur(img, img, Size(3, 3), 0);
	cvtColor(img, img, COLOR_BGR2GRAY);
	Mat dst;
	threshold(img, dst, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
	imshow("二值化分割", dst);
	vector<vector<Point>>contours;
	vector<Vec4i>hierarchy;
	//Mat result = Mat::zeros(img.size(), CV_8UC3);
	findContours(dst, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	/*double minLength;
	cout << "输入最小周长" << endl;
	cin >> minLength;
	double minArea;
	cout << "输入最小面积" << endl;
	cin >> minArea;*/
	for (int i = 0; i < contours.size(); i++)
	{
		if (arcLength(contours[i],true) < 100 || contourArea(contours[i]) < 10) continue;
		//最大外接矩形
		Rect maxRect = boundingRect(contours[i]);
		rectangle(result, maxRect, Scalar(200, 20, 20), 2, 8);
		//最小外接矩形
		RotatedRect minRect = minAreaRect(contours[i]);
		ellipse(result, minRect, Scalar(20, 200, 20), 2, 8);
		Point2f pts[4];
		//通过点连接成线绘制最小外接矩形
		minRect.points(pts);
		for (int i = 0; i < 4; i++)
		{
			line(result, pts[i], pts[(i + 1)%4], Scalar(20, 20, 200), 2, 8);
		}
		drawContours(result, contours, -1, Scalar(100, 100, 100), 2, 8);
		cout << "轮廓" << i << "面积: " << contourArea(contours[i]) << "\t" << "轮廓" << i << "周长: " << arcLength(contours[i], true) << endl;
	}
	imshow("输出", result);
}

//轮廓比较
void contoursFn( Mat &dst, const vector<vector<Point>> &imgContours, const vector<vector<Point>>& srcContours)
{
	Moments srcMm = moments(srcContours[0]);
	Mat srcHu;
	HuMoments(srcMm, srcHu);
	for (int i = 0; i < imgContours.size(); i++)
	{
		Mat imgHu;
		Moments imgMm = moments(imgContours[i]);
		double pX = imgMm.m10 / imgMm.m00;
		double pY = imgMm.m01 / imgMm.m00;
		circle(dst, Point(pX, pY), 3, Scalar(200, 200, 20), 2, LINE_8);
		HuMoments(imgMm, imgHu);
		double ss = matchShapes(imgHu, srcHu, CONTOURS_MATCH_I1,0);
		//cout << ss << endl;
		if (ss < 2.0)
		{
			cout << ss << endl;
			drawContours(dst, imgContours, i, Scalar(20, 20, 200), 2, 8);
		}
		else
		{
			cout << "匹配不成功" << endl;
		}
	}
	imshow("axx", dst);
	/*for (int i = 0; i < srcContours.size(); i++)
	{
		moImg.push_back(moments(srcContours[i]));
	}*/
	
}
void Person::contourComp(Mat& img, Mat& src)
{
	namedWindow("匹配轮廓图", WINDOW_FREERATIO);
	imshow("匹配轮廓图", src);
	Mat binaryImg = this->myThresh(img);
	Mat binarysrc = this->myThresh(src);
	vector<vector<Point>> imgContours;
	vector<vector<Point>> srcContours;
	vector<Vec4i> hierarchy;
	vector<Vec4i> hierarchy1;
	findContours(binaryImg, imgContours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	findContours(binarysrc, srcContours, hierarchy1, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	contoursFn(img, imgContours, srcContours);
}

//根据轮廓拟合
void Person::contourProx(Mat& img)
{
	imshow("原图", img);
	Mat binaryImg = this->myThresh(img);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(binaryImg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	for (int i = 0; i < contours.size(); i++)
	{
		Mat poly;
		approxPolyDP(contours[i], poly, 4, true);
		cout << "图形:" << i << "行数 " << poly.rows << "列数: " << poly.cols << endl;
		double len = arcLength(contours[i], true);
		double Area = contourArea(contours[i]);
		Moments mm = moments(contours[i]);
		double pX = mm.m10 / mm.m00;
		double pY = mm.m01 / mm.m00;
		//if (poly.rows = 4)
		//{
		//	putText(img, "矩形", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
		//	string Sarea = "面积: " + to_string(Area);
		//	string Slen = "周长: " + to_string(len);
		//	/*putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
		//	putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
		//	circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
		//}
		//if (poly.rows = 3)
		//{
		//	putText(img, "三角形", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
		//	string Sarea = "面积: " + to_string(Area);
		//	string Slen = "周长: " + to_string(len);
		//	/*putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
		//	putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
		//	circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
		//}
		//if (poly.rows = 6)
		//{
		//	putText(img, "6边形", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
		//	string Sarea = "面积: " + to_string(Area);
		//	string Slen = "周长: " + to_string(len);
		///*	putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
		//	putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
		//	circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
		//}
		//if (poly.rows > 12)
		//{
		//	putText(img, "圆", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
		//	string Sarea = "面积: " + to_string(Area);
		//	string Slen = "周长: " + to_string(len);
		///*	putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
		//	putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
		//	circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
		//}
		putText(img, "我", Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
	}
	imshow("判断轮廓图像", img);
}


void Person::myImg(Mat& img)
{
	if (img.empty())
	{
		cout << "图片路径错误" << endl;
		return ;
	}
	imshow("原图", img);
}

void Person::myThreshold(Mat& img)
{
	Mat gray; Mat binary;
	cvtColor(img, gray, COLOR_BGR2GRAY);
	//通过mean求阈值T
	Scalar T = mean(gray);
	threshold(gray, binary, T[0], 255, THRESH_BINARY);
	cout << "全局阈值T: " << T[0] << endl;
	imshow("全局阈值", binary);

	//通过otsu求
	double otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("otsu", binary);
	cout << "otsu: " << otsu << endl;

	//三角法
	double trian = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
	imshow("trian", binary);
	cout << "triangle: " << trian << endl;
}

//返回除燥的灰色图像
Mat Person::myGray(Mat& img)
{
	Mat gray; Mat binary; 
	GaussianBlur(img, img, Size(3, 3), 0);
	cvtColor(img, gray, COLOR_BGR2GRAY);
	return gray;
}

//返回二值化
Mat Person::myBinary(Mat& img)
{
	Mat binary;
	Mat gray = this->myGray(img);
	//threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
	 threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
	return binary;
}


void Person::adpThreshold(Mat& img)
{
	Mat dst; Mat dst1;
	imshow("原图", img);
	Mat binary = this->myGray(img);
	imshow("灰色", binary);
	double T = threshold(binary, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("全局阈值", dst);
	adaptiveThreshold(binary, dst1, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 23, 5);
	imshow("自适应阈值", dst1);
}

//联通组件
void Person::myCopNect(Mat& img)
{
	RNG rng(12345);
	imshow("原图", img);
	Mat binary = this->myBinary(img);
	imshow("二值化", binary);
	Mat labels = Mat::zeros(img.size(), CV_32S);
	int num = connectedComponents(binary, labels, 8, CV_32S, CCL_DEFAULT);
	cout << "组件" << num - 1 << endl;
	vector<Vec3b> vec(num);
	vec[0] = Vec3b(0, 0, 0);
	for (int i = 1; i < vec.size(); i++)
	{
		vec[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
	}
	Mat src = Mat::zeros(img.size(), img.type());
	for (int y = 0; y < img.rows; y++)
	{
		for (int x = 0; x < img.cols; x++)
		{
			int label = labels.at<int>(y, x);
			src.at<Vec3b>(y, x) = vec[label];
		}
	}
	imshow("lable", src);
}

void Person::compnect1(Mat& img)
{
	imshow("原图", img);
	RNG rng(12345);
	Mat  binary = this->myBinary(img);
	Mat labels = Mat::zeros(img.size(),CV_32S);
	Mat stats; Mat centroids;
	int num = connectedComponentsWithStats(binary, labels, stats, centroids, 8, CV_32S, CCL_DEFAULT);
	Mat result = Mat::zeros(img.size(), CV_8UC3);
	vector<Vec3b> color(num);
	color[0] = Vec3b(0, 0, 0);
	for (int i = 1; i < num; i++)
	{
		color[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
	}
	for (int row = 0; row < img.rows; row++)
	{
		for (int col = 0; col < img.cols; col++)
		{
			int lable = labels.at<int>(row, col);
			result.at<Vec3b>(row, col) = color[lable];
		}
	}
	for (int i = 1; i < num; i++)
	{
		double pX = centroids.at<double>(i, 0);
		double pY = centroids.at<double>(i, 1);
		int left = stats.at<int>(i, CC_STAT_LEFT);
		int top = stats.at<int>(i, CC_STAT_TOP);
		int width = stats.at<int>(i, CC_STAT_WIDTH);
		int height = stats.at<int>(i, CC_STAT_HEIGHT);
		string area = to_string( stats.at<int>(i, CC_STAT_AREA));
		putText(result, area, Point(pX - 10, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(200, 20, 20), 2, 8);
		rectangle(result,Rect(left,top,width,height),Scalar(20,20,200),2,8);
	}
	putText(result, to_string(num - 1), Point(50, 50), FONT_HERSHEY_PLAIN, 2, Scalar(150, 150, 150));
	imshow("connect", result);
}

//轮廓发现
void Person::myContours(Mat& img)
{
	Mat result = Mat::zeros(img.size(), CV_8UC3);
	imshow("原图", img);
	Mat binary = this->myBinary(img);
	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	findContours(binary, contours, hierachy, RETR_LIST,CHAIN_APPROX_SIMPLE, Point());
	//drawContours(result, contours, -1, Scalar(0, 0, 200), 2, 8);
	for (int i = 0; i < contours.size(); i++)
	{
		drawContours(result, contours, i, Scalar(0, 0, 200), 2, 8);
	}
	imshow("轮廓", result);
}

void Person::myContours1(Mat& img)
{
	imshow("原图", img);
	Mat binary = this->myBinary(img);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	for (int i = 0; i < contours.size(); i++)
	{
		double area = contourArea(contours[i]);
		double length = arcLength(contours[i], true);
		if (area < 100 || length <10) continue;
		drawContours(img, contours, i,Scalar(0,0,200),-1,8);

		Rect box = boundingRect(contours[i]);
		rectangle(img, box, Scalar(200, 0, 0), 2, 8);

		ellipse(img, minAreaRect(contours[i]), Scalar(0, 200, 0), 2, 8);

		Point2f poin[4];
		RotatedRect roRec = minAreaRect(contours[i]);
		roRec.points(poin);
		for (int i = 0; i < 4; i++)
		{
			line(img, poin[i], poin[(i + 1) % 4], Scalar(157, 157, 157), 2, 8);
		}
	}
	imshow("轮廓", img);
}

void Person::momentCop(Mat& img,Mat &img1)
{
	imshow("模板", img);
	imshow("匹配", img1);
	Mat binary = this->myBinary(img);
	Mat binary1 = this->myBinary(img1);
	vector<vector<Point>> contours;
	vector<vector<Point>> contours1;
	vector<Vec4i> hierarchy;
	vector<Vec4i> hierarchy1;
	findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	findContours(binary1, contours1, hierarchy1, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	Mat src; Mat src1;
	cout << contours.size() << endl;
	for (int i = 0; i < contours.size(); i++)
	{
		Moments res = moments(contours[i]);
		Moments res1 = moments(contours1[0]);
		HuMoments(res, src);
		HuMoments(res1, src1);
		double num = matchShapes(src, src1, CONTOURS_MATCH_I1, 0);
		if (num < 2)
		{
			drawContours(img, contours, i, Scalar(0, 0, 200), 2, 8);
			
		}
		cout << num << endl;
		double pX = res.m10 / res.m00;
		double pY = res.m01 / res.m00;
		circle(img, Point(pX, pY), 3, Scalar(200, 0, 0), 2, 8);
	}
	imshow("模板", img);
}

void Person::approxP(Mat& img)
{
	imshow("原图", img);
	Mat binary = this->myBinary(img);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	Mat src;
	for (int i = 0; i < contours.size(); i++)
	{
		double pX = moments(contours[i]).m10 / moments(contours[i]).m00;
		double pY = moments(contours[i]).m01 / moments(contours[i]).m00;
		approxPolyDP(contours[i], src, 4, true);
		cout << "端点数量: " << src.rows << endl;
		if (src.rows == 4)
		{
			putText(img, "rec", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
			circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
		}
		if (src.rows == 3)
		{
			putText(img, "triangle", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
			circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
		}
		if (src.rows == 6)
		{
			putText(img, "hex", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
			circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
		}
		if (src.rows > 10)
		{
			putText(img, "ploy", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
			circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
		}
	}
	imshow("图形判断", img);
}

//返回二值化轮廓
vector<vector<Point>> Person::contourOne(Mat& img)
{
	Mat binary = this->myBinary(img);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	return contours;
}

//拟合
void Person::myFitEllipse(Mat& img)
{
	imshow("原图", img);
	vector<vector<Point>> contours = this->contourOne(img);
	for (int i = 0; i < contours.size(); i++)
	{
		 RotatedRect rotRect = fitEllipse(contours[i]);
		 Point center = rotRect.center;
		 string height = to_string(rotRect.size.height);
		 string width = to_string(rotRect.size.width);
		 string are = to_string(rotRect.size.area());
		 ellipse(img, rotRect, Scalar(255, 0, 10), 2, 8);
		 circle(img, center, 3, Scalar(0, 255, 0), 2, LINE_8);
	}
	imshow("处理图", img);
	
}

//霍夫直线
void Person::Houline(Mat& img)
{
	imshow("原图", img);
	Mat binary = this->myBinary(img);
	vector<Vec3f>lines;
	HoughLines(binary, lines, 1, CV_PI / 180, 160, 0, 0);
	Point p1; Point p2;
	for (int i = 0; i < lines.size(); i++)
	{
		double step = lines[i][0];
		double angle = lines[i][1];
		double add = lines[i][2];
		cout << "直线" << i << "\t" << "距离: " << step << "角度: " << angle << i << "累加点: " << add << endl;
		double x = cos(angle);
		double y = sin(angle);
		double x0 = step * x;
		double y0 = step * y;
		p1.x = cvRound(x0 + 500 * -y);
		p1.y = cvRound(y0 + 500 * x);
		p2.x = cvRound(x0 - 500 * -y);
		p2.y = cvRound(y0 - 500 * x);
		line(img, p1, p2, Scalar(0, 0, 255), 2, 8);
	}
	imshow("霍夫直线", img);
}

//霍夫线段
void Person::houlineP(Mat& img)
{
	Mat result = Mat::zeros(img.size(), img.type());
	imshow("原图", img);
	Mat binary = this->myBinary(img);
	vector<Vec4i> lines;
	imshow("binary",binary);
	HoughLinesP(binary, lines, 1, CV_PI / 180, 80,30,10);
	//Point p1; Point p2;
	for (int i = 0; i < lines.size(); i++)
	{
		/*p1.x = lines[i][0];
		p1.y = lines[i][1];
		p2.x = lines[i][2];
		p2.y = lines[i][3];*/
		//line(result, p1, p2, Scalar(0, 0, 255), 1, 8);
		line(result, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(255, 0, 0), 1, 8);
	}
	imshow("霍夫直线", result);
}

//霍夫圆检测
void Person::houghCir(Mat &img)
{
	imshow("原图", img);
	Mat result = Mat::zeros(img.size(), CV_8UC3);
	Mat gray;
	cvtColor(img, gray, COLOR_BGR2GRAY);
	GaussianBlur(gray, gray, Size(15,15), 2, 2);
	vector<Vec3f> cir;
	int dp = 2;
	double cirSpace = 5;
	int add = 100;
	int maxThreshold = 100;
	double cirMin = 15; double cirMax = 100;
	HoughCircles(gray, cir, HOUGH_GRADIENT, dp, cirSpace, add, maxThreshold, cirMin, cirMax);
	for (int i = 0; i < cir.size(); i++)
	{
		int cenX = round(cir[i][0]);
		int cenY = round(cir[i][1]);
		int radius = round(cir[i][2]);
		circle(result, Point(cenX, cenY), radius, Scalar(0, 0, 200), 2, 8);
	}
	imshow("霍夫找园", result);
}


void Person::erodeDilate(Mat& img)
{
	imshow("原图", img);
	Mat result; 
	Mat result1;
	Mat binary = this->myBinary(img);
	Mat rect = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	erode(img, result1, rect);
	imshow("腐蚀", result1);
	dilate(img, result, rect);
	imshow("膨胀", result);
}

//开闭操作
void Person::openCloss(Mat& img)
{
	Mat dst;
	imshow("原图", img);
	Mat binary = this->myBinary(img);
	imshow("二值化", binary);
	Mat kernel =  getStructuringElement(MORPH_RECT, Size(15, 1), Point(-1, -1));
	morphologyEx(binary, dst, MORPH_OPEN, kernel, Point(-1, -1), 1);
	imshow("腐蚀", dst);
}

//形态学梯度
void Person::gradi(Mat& img)
{
	
	if (img.empty())
	{
		cout << "图片路径错误" << endl;
		return;
	}
	imshow("原图", img);
	Mat gray; Mat binary;
	cvtColor(img, gray, COLOR_BGR2GRAY);
	Mat Ksize = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	Mat grad; Mat inside; Mat extral; Mat src; Mat src1;
	erode(gray, src, Ksize, Point(-1, -1));
	dilate(gray, src1, Ksize, Point(-1, -1));
	subtract(src1, src, grad);
	subtract(gray, src, inside);
	subtract(src1, gray, extral);
	imshow("形态学", grad);
	threshold(grad, grad, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
	imshow("基本形态学梯度", grad);
}

//黑帽和顶帽
void Person::morph1(Mat& img)
{
	imshow("原图", img);
	Mat binary = this->myBinary(img);
	Mat dst;
	Mat rect = getStructuringElement(MORPH_ELLIPSE, Size(14, 14), Point(-1, -1));
	imshow("二值化", binary);
	//MORPH_TOPHAT
	morphologyEx(binary, dst, MORPH_BLACKHAT, rect);
	imshow("顶帽", dst);
}

//击中与不击中
void Person::morph2(Mat& img)
{
	imshow("原图", img);
	Mat dst;
	Mat binary = this->myBinary(img);
	Mat rect = getStructuringElement(MORPH_CROSS, Size(12, 12), Point(-1, -1));
	morphologyEx(binary, dst, MORPH_HITMISS, rect);
	imshow("匹配模板", dst);
}

//处理小案列
void Person::case1(Mat& img)
{
	Mat dst = Mat::zeros(img.size(), img.type());
	if (img.empty())
	{
		cout << "路径错误" << endl;
		return;
	}
	imshow("原图", img);
	Mat src; Mat gray; Mat binary;
	GaussianBlur(img, src, Size(3, 3), 0);
	cvtColor(src, gray, COLOR_BGR2GRAY);
	threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("二值化", binary);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	double are1;
	int maxAre = -1;
	int index = -1;
	cout << contours.size() << endl;
	cout << "最终111" << "\t" << index << endl;
	for (int i = 0; i < contours.size(); i++)
	{
		Rect rec = boundingRect(contours[i]);
		if (rec.width >= img.cols || rec.height > img.rows) continue;
		int area = round( contourArea(contours[i]));
		cout << "面积:" << area << endl;
		double leng = arcLength(contours[i],true);
		if (maxAre < area)
		{
			maxAre = area;
			index = i;
		}
	}
	drawContours(dst, contours, index, Scalar(255, 0, 0), 2, 8);
	Mat pts;
	approxPolyDP(contours[index], pts, 4, false);
	for (int i = 0; i < pts.rows; i++)
	{
		Vec2i pt = pts.at<Vec2i>(i, 0);
		circle(dst, Point(pt[0], pt[1]), 3, Scalar(0, 0, 255), 2, 8);
	}
	imshow("shuchu ", dst);
	
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值