## 采用函数识别金字塔

采用函数识别金字塔

#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/types_c.h>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/core.hpp>
#include <opencv2/objdetect.hpp>
#include <iostream>

using namespace cv;
using namespace std;

//函数drawing识别轮廓,然后绘制最小外接矩形
Mat drawing(Mat ima, Mat gray) {


	double total_area = 13.86*13.86;//所加工的金字塔总面积
	double pixel_area = total_area / 948675;//在当前摄影条件下,平均每个像素面积
	int blockSize = 105;//邻域范围(2-40:95,-35)(50:95,-20)(60:95,-5)(70-80:385,-5)
	int constValue = -15;//补偿值
	cv::Mat local; //局部二值化图像local
	cv::adaptiveThreshold(gray, local, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, blockSize, constValue);

	//imshow("global", global);
	//imshow("local", local);
	int rows = local.rows; //获取图像像素行
	int cols = local.cols;    //获取图像像素列

	vector<vector<Point>> contours;  // 轮廓容器
	//vector<vector<Point>> contours1;
	Rect centerRect(rows / 2 - 5, cols / 2 - 5, 10, 10); //定义中心矩阵

	vector<Vec4i> hierarcy;
	findContours(local, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);//local
	vector<Rect> boundRect(contours.size());  //定义外接矩形集合
	vector<RotatedRect> box(contours.size()); //定义最小外接矩形集合
   // vector<Point> cen;  //中心点集合
	Point2f rect[4];
	//Point cen
	for (int i = 0; i < contours.size(); i++)
	{
		box[i] = minAreaRect(Mat(contours[i]));  //计算每个轮廓最小外接矩形2         boundRect[i] = boundingRect(Mat(contours[i]));
		double area = (box[i].size.width)* (box[i].size.height);//计算面积
		if (area > 1)
		{
			//cout << "矩形面积为: " << area << endl;
			//判断外接矩形的中心点是否为图片的中心
			if (box[i].center.x > centerRect.x && box[i].center.y > centerRect.y &&  box[i].center.y < centerRect.y + centerRect.height &&box[i].center.x < centerRect.x + centerRect.width)

			{

				circle(ima, Point(box[i].center.x, box[i].center.y), 2, Scalar(0, 255, 0), 1, 8);  //绘制最小外接矩形的中心点
				cout << "矩形总像素为: " << area << "像素" << endl; //area 为识别后的外接矩形总像素
				cout << "矩形总面积为: " << area * pixel_area << "mm2" << endl;
				box[i].points(rect);  //把最小外接矩形四个端点复制给rect数组
				//double area = (box[i].size.width)* (box[i].size.height);//计算面积
				//cout << "矩形面积为: " << area << endl;
				rectangle(ima, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
				//double recArea = contourArea(box[i],false);
				for (int j = 0; j < 4; j++)
				{
					line(ima, rect[j], rect[(j + 1) % 4], Scalar(0, 0, 255), 1, 8);  //绘制最小外接矩形每条边
				}
			}
		}
	}

		return ima;
}


int main(int argc, char** argv)
{
	//cv::Mat image = cv::imread("H://图片//0.90.jpg");//载入图像
	//cv::Mat imageGray;
	//cvtColor(image, imageGray, COLOR_BGR2GRAY); //转换为灰度图像
	//IplImage* img = cvLoadImage("E://image//1.png");
	/*if (imageGray.empty())
	{
		std::cout << "read image failure" << std::endl;
		return -1;
	}*/

	/*RNG rng((unsigned)time(NULL)); //生成随机数
		Mat Canny_output;
		vector<vector<Point>> contours; //边缘矢量
		vector<Vec4i> hierarchy;   //形状因子
		Canny(local, Canny_output, 200, 500, 3);  //边缘检测

		imshow("canny", Canny_output);

		findContours(Canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); //轮廓提取
		Mat drawing = Mat::zeros(Canny_output.size(), CV_8UC3); //新建一样大小的图像
		for (int i = 0; i < contours.size();i++)   //每个新的边缘赋RBG随机数
		{
			Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
			drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point()); //画出轮廓
		}
		imshow("contours", drawing);*/


		//	Mat result;
		//	Canny(image, result, 50, 150, 3);
		//	//cv::imshow("localThreshold", local);
			//imshow("jieguo", result);


		//使用不同的二值化方法,再进行判断

			// 全局二值化

	string pattern = "H://图片//cut//(5.5)//*.jpg"; //存放图片的路径
	//cout << pattern << endl;
	vector<Mat> images; //图片Mat类合集
	// 必须cv的String
	vector<String> fn;
	glob(pattern, fn, false);
	size_t count = fn.size();
	cout << count << endl;
	//double total_area = 13.86*13.86;//所加工的金字塔总面积
	//double pixel_area = total_area / 948675;//在当前摄影条件下,平均每个像素面积
	char filename[100];
	Mat imageGray;

	for (int i = 0; i < count; i++)
	{
		cout << i << endl;
		images.push_back(imread(fn[i])); //push_back为在数据后面添加一行矩阵
		//int width = images[i].rows;
		//int height = images[i].cols;
		//int total = width * height;
		//cout << "图片" << i << "总像素为" << total << endl;
		//Mat imageGray;
		cvtColor(images[i], imageGray, COLOR_BGR2GRAY); //转换为灰度图像


		/*int th = 100;
		cv::Mat global;//全局二值化图像global
		cv::threshold(imageGray, global, th, 255, CV_THRESH_BINARY);*/


		// 局部自适应阈值二值化
		/*
		int blockSize = 95;//邻域范围(2-40:95,-35)(50:95,-20)(60:95,-5)(70-80:385,-5)
		int constValue = -5;//补偿值
		cv::Mat local; //局部二值化图像local
		cv::adaptiveThreshold(imageGray, local, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, blockSize, constValue);

		//imshow("global", global);
		imshow("local", local);




		int rows = local.rows; //获取图像像素行
		int cols = local.cols;    //获取图像像素列

		vector<vector<Point>> contours;  // 轮廓容器
		//vector<vector<Point>> contours1;
		Rect centerRect(rows / 2 -5 , cols / 2 - 5, 10, 10); //定义中心矩阵

		vector<Vec4i> hierarcy;
		findContours(local, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);//local
		vector<Rect> boundRect(contours.size());  //定义外接矩形集合
		vector<RotatedRect> box(contours.size()); //定义最小外接矩形集合
	   // vector<Point> cen;  //中心点集合
		Point2f rect[4];
		//Point cen
		for (int i = 0; i < contours.size(); i++) 
		{
			box[i] = minAreaRect(Mat(contours[i]));  //计算每个轮廓最小外接矩形2         boundRect[i] = boundingRect(Mat(contours[i]));
			double area = (box[i].size.width)* (box[i].size.height);//计算面积
			if (area > 1)
			{
				//cout << "矩形面积为: " << area << endl;
				//判断外接矩形的中心点是否为图片的中心
				if (box[i].center.x > centerRect.x && box[i].center.y > centerRect.y &&  box[i].center.y < centerRect.y + centerRect.height &&box[i].center.x < centerRect.x + centerRect.width)

				{

					circle(images[i], Point(box[i].center.x, box[i].center.y), 2, Scalar(0, 255, 0), -1, 8);  //绘制最小外接矩形的中心点
					cout << "矩形总像素为: " << area <<"像素"<< endl; //area 为识别后的外接矩形总像素
					cout << "矩形总面积为: " << area*pixel_area <<"mm2"<< endl;
					box[i].points(rect);  //把最小外接矩形四个端点复制给rect数组
					//double area = (box[i].size.width)* (box[i].size.height);//计算面积
					//cout << "矩形面积为: " << area << endl;
					rectangle(images[i], Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
					//double recArea = contourArea(box[i],false);
					for (int j = 0; j < 4; j++)
					{
						line(images[i], rect[j], rect[(j + 1) % 4], Scalar(0, 0, 255), 2, 8);  //绘制最小外接矩形每条边
					}
				}
			}
		}*/
		images[i] = drawing(images[i], imageGray);

		imshow("dst", images[i]);
		sprintf_s(filename, "H://图片//result//%u.jpg", i+1);//赋予文件名
		imwrite(filename, images[i]);//保存图片

	}



	/*	if (local.at<uchar>((local.rows) / 2, (local.cols) / 2)  = 0 && global.at<uchar>((local.rows) / 2, (local.cols) / 2)  > 0)

			//cv::imwrite("global.jpg", global);
			//cv::imwrite("local.jpg", local)
		{

			int global_whiteNum = 0;
			int global_blackNum = 0;
			int rows = global.rows;
			int cols = global.cols;
			for (int j = 0; j < rows; j++)//遍历二值图像
			{
				for (int i = 0; i < cols; i++)
				{
					if (global.at<uchar>(j, i) > 0) //计算黑白像素点总个数
					{
						global_whiteNum++;
					}
					else global_blackNum++;
				}
			}
			imshow("image", image);
			imshow("Gray", imageGray);
			cv::imshow("globalThreshold", global);
			//cv::imshow("localThreshold", local);
			cout << "global白色像素点一共有:" << global_whiteNum << endl;
			cout << "global黑色像素点一共有:" << global_blackNum << endl;




		}

		else {

			int local_blackNum = 0;
			int local_whiteNum = 0;
			int rows = local.rows;
			int cols = local.cols;
			for (int j = 0; j < rows; j++)
			{
				for (int i = 0; i < cols; i++)
				{
					if (local.at<uchar>(j, i) > 0)
					{
						local_whiteNum++;
					}
					else local_blackNum++;
				}
			}

			imshow("image", image);
			imshow("Gray", imageGray);
			//cv::imshow("globalThreshold", global);
			cv::imshow("localThreshold", local);
			cout << "local白色像素点一共有:" << local_whiteNum << endl;
			cout << "local黑色像素点一共有:" << local_blackNum << endl;
		}

		*/
	cv::waitKey(0);


	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值