采用函数识别金字塔
#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;
}