(一)opencv颜色提取后输出最小矩形的坐标

此代码的目的是通过颜色识别提取零件缺陷部位,用三视图方法将复杂的三维缺陷形状简化为简单的长方体,并通过定位长方体顶点坐标,去除缺陷部位以便后续替换新材料。

#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>

#define win "【阈值】"
#define pic_name " z "

using namespace cv;
using namespace std;

Mat src, src_hsv, imgThresh, edge,drawing;

int h_min = 0;
int h_max = 10;

int s_min = 43;
int s_max = 255;

int v_min = 0;
int v_max = 255;

vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
vector<Rect> boundRect(contours.size());

void on_threshold(int, void*);


int main(int argc, char** argv)
{
	Mat src = imread("C:/Users/Administrator/Desktop/三维重建/图片/z.PNG"); 
	if (!src.data)
	{
		cout << "could not load image...\n";
		return -1;
	}

	namedWindow("input", WINDOW_AUTOSIZE);	
	namedWindow(win, WINDOW_AUTOSIZE);
	cvtColor(src, src_hsv, COLOR_BGR2HSV);
	imshow("input", src);

	/***************************************【颜色识别】****************************************/
	createTrackbar("min_H", win, &h_min, 180, on_threshold);
	createTrackbar("max_H", win, &h_max, 180, on_threshold);
	createTrackbar("min_S", win, &s_min, s_max, on_threshold);
	createTrackbar("max_S", win, &s_max, s_max, on_threshold);
	createTrackbar("min_V", win, &v_min, v_max, on_threshold);
	createTrackbar("max_V", win, &v_max, v_max, on_threshold);
	on_threshold(0, 0);
	
	waitKey(0);
	return 0;
}

void on_threshold(int, void*)
{
	vector<Mat> hsvSplit;
	split(src_hsv, hsvSplit);
	equalizeHist(hsvSplit[2], hsvSplit[2]);
	merge(hsvSplit, src_hsv);
	inRange(src_hsv, Scalar(h_min, s_min, v_min), Scalar(h_max, s_max, v_max), imgThresh);
	imshow("thresh", imgThresh);
	
	Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
	morphologyEx(imgThresh, imgThresh, MORPH_OPEN, element);
	morphologyEx(imgThresh, imgThresh, MORPH_CLOSE, element);
	Canny(imgThresh, edge, 3, 9, 3);

	findContours(edge, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	vector<Rect> boundRect(contours.size());

	drawing = Mat::zeros(edge.size(), CV_8UC3);
	for (int i = 0; i < contours.size(); i++)
	{
		boundRect[i] = boundingRect(Mat(contours[i]));
		Scalar color(0, 255, 0);
		
		drawContours(drawing, contours, i, color, 1, 8, hierarchy);
	    rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 0, 255), 1, 8);
		fstream outfile("坐标.txt");
		cout << pic_name << ":" << endl;
		cout << "P1 = " << boundRect[i].tl()*0.265  << " mm" << endl;
		cout << "P2 = " << boundRect[i].br()*0.265 << " mm"  << endl;

		outfile << pic_name << ":" << endl;
		outfile << "P1 = " << boundRect[i].tl()*0.265 << "mm" << endl;
		outfile << "P2 = " << boundRect[i].br()*0.265 << "mm" << endl;
		outfile.close();
		imwrite(pic_name".png", drawing);
	}
	imshow("output", drawing);
}

在这里插入图片描述p1为矩形左上角坐标,p2为右下角坐标通过这两个坐标即可确定矩形的整个坐标,边长以及面积图片上的坐标为像素坐标,代码中已转换为毫米坐标

此代码还未正式完成!

猜你喜欢

转载自blog.csdn.net/weixin_43066495/article/details/83932312