【OpenCV學習筆記】二十七、輪廓特徵屬性及應用(四)——正外接矩形

輪廓特徵屬性及應用(四)——正外接矩形

1.輪廓正外接矩形——boundingRect()

2.完成了三個小應用:正外接矩形的查找繪製、分割硬幣輪廓、簡單車牌字符分割

先上ppt:








代碼:

正外接矩形的查找繪製:

///正外接矩形的查找繪製
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	//1.查找輪廓
    //1.1查找輪廓前的預處理(灰度圖,閾值化)
	Mat srcImg = imread("12.jpg",CV_LOAD_IMAGE_COLOR);
	imshow("srcImg", srcImg);
	Mat copyImg = srcImg.clone();
	cvtColor(srcImg,srcImg,CV_BGR2GRAY);
	threshold(srcImg,srcImg,100,255,CV_THRESH_BINARY);
	imshow("threshold",srcImg);
	vector <vector<Point>> contours;
	vector<Vec4i> hierarcy;//沒用到
	//1.2查找輪廓
    findContours(srcImg,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);//最外層輪廓
	//1.3繪製所有輪廓
	drawContours(copyImg,contours,-1,Scalar(0,255,0),1,8);
	//2.由輪廓確定正外接矩形
	int width = 0;
	int height = 0;
	int x = 0;
	int y = 0;
	//2.1 定義Rect類型的vector容器boundRect存放正外接矩形,初始化大小爲contours.size()即輪廓個數
	vector<Rect> boundRect(contours.size());
	//2.2 遍歷每個輪廓
	for (int i = 0; i < contours.size(); i++)
	{
		//2.3由輪廓(點集)確定出正外接矩形
		boundRect[i] = boundingRect(Mat(contours[i]));
		//2.4獲得正外接矩形的左上角座標及寬高
		width = boundRect[i].width;
		height = boundRect[i].height;
		x = boundRect[i].x;
		y = boundRect[i].y;
		//2.5用畫矩形方法繪製正外接矩形
		rectangle(copyImg,Rect(x,y,width,height),Scalar(0,0,255),1,8);
	}
	imshow("輪廓和正外接矩形", copyImg);
	waitKey(0);
	return 0;
}

運行結果:



分割硬幣輪廓:

///分割硬幣輪廓
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	//1.查找輪廓
	//1.1查找輪廓前的預處理(灰度圖,閾值化)
	Mat srcImg = imread("33.png",CV_LOAD_IMAGE_COLOR);
	imshow("srcImg", srcImg);
	Mat copyImg = srcImg.clone();
	cvtColor(srcImg,srcImg,CV_BGR2GRAY);
	threshold(srcImg,srcImg,100,255,CV_THRESH_BINARY);
	imshow("threshold",srcImg);
	//*1.2增加了膨脹和腐蝕
	//因爲有一個輪廓有斷點,導致外接矩形是兩個小的而不是一個整的,故要膨脹,將斷點連起來
	//1.2.1定義kernel
	Mat kernel = getStructuringElement(MORPH_RECT,Size(5,5),Point(-1,-1));
	//1.2.2膨脹
	dilate(srcImg,srcImg,kernel,Point(-1,-1));
	//1.2.3腐蝕
	erode(srcImg,srcImg,kernel,Point(-1,-1));
	imshow("膨脹和腐蝕", srcImg);
	//1.3查找輪廓
	vector <vector<Point>> contours;
	vector<Vec4i> hierarcy;//沒用到
	findContours(srcImg,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);//最外層輪廓
	//1.4繪製所有輪廓
	drawContours(copyImg,contours,-1,Scalar(0,255,0),1,8);
	//2.由輪廓確定正外接矩形
	int width = 0;
	int height = 0;
	int x = 0;
	int y = 0;
	//2.1 定義Rect類型的vector容器boundRect存放正外接矩形,初始化大小爲contours.size()即輪廓個數
	vector<Rect> boundRect(contours.size());
	//2.2 遍歷每個輪廓
	for (int i = 0; i < contours.size(); i++)
	{
		//2.3由輪廓(點集)確定出正外接矩形
		boundRect[i] = boundingRect(Mat(contours[i]));
		//2.4獲得正外接矩形的左上角座標及寬高
		width = boundRect[i].width;
		height = boundRect[i].height;
		x = boundRect[i].x;
		y = boundRect[i].y;
		//*2.5 對正外接矩形進行篩選(過濾掉小的)
		if (width>40 && height > 40)
		{
			//2.6用畫矩形方法繪製正外接矩形
			rectangle(copyImg, Rect(x, y, width, height), Scalar(0, 0, 255), 1, 8);
		}
	}
	imshow("輪廓和正外接矩形", copyImg);
	waitKey(0);
	return 0;
}

運行結果:



簡單車牌字符分割:

///簡單車牌字符分割
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	//1.查找輪廓
	//1.1查找輪廓前的預處理(灰度圖,閾值化)
	Mat srcImg = imread("Car.jpg", CV_LOAD_IMAGE_COLOR);
	imshow("srcImg", srcImg);
	Mat copyImg = srcImg.clone();
	cvtColor(srcImg, srcImg, CV_BGR2GRAY);
	threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
	imshow("threshold", srcImg);
	//1.2查找輪廓
	vector <vector<Point>> contours;
	vector<Vec4i> hierarcy;//沒用到
	findContours(srcImg, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);//所有輪廓
	//1.3繪製所有輪廓
	drawContours(copyImg, contours, -1, Scalar(0, 255, 0), 1, 8);
	//2.由輪廓確定正外接矩形
	int width = 0;
	int height = 0;
	int x = 0;
	int y = 0;
	//2.1 定義Rect類型的vector容器boundRect存放正外接矩形,初始化大小爲contours.size()即輪廓個數
	vector<Rect> boundRect(contours.size());
	//2.2 遍歷每個輪廓
	for (int i = 0; i < contours.size(); i++)
	{
		//2.3由輪廓(點集)確定出正外接矩形
		boundRect[i] = boundingRect(Mat(contours[i]));
		//2.4獲得正外接矩形的左上角座標及寬高
		width = boundRect[i].width;
		height = boundRect[i].height;
		x = boundRect[i].x;
		y = boundRect[i].y;
		//*2.5 對正外接矩形進行篩選(過濾掉過小及過大的)
		if (width>(1.0 / 12)*srcImg.cols && width<(1.0 / 7)*srcImg.cols 
			 &&height >(1.0 / 6)*srcImg.rows&& height < (5.0 / 6)*srcImg.rows)
		{
			//2.6用畫矩形方法繪製正外接矩形
			rectangle(copyImg, Rect(x, y, width, height), Scalar(0, 0, 255), 1, 8);
			//*2.7 通過ROI保存分割出的車牌字符
			//2.7.1 定義ROI
			Mat ROI = copyImg(Rect(x,y,width,height));
			//2.7.2 通過sprintf格式化文件存儲名name
			char name[20] = {0};
			sprintf(name,"E:\\temp\\%d.jpg",i);
			//2.7.3 寫ROI到本地
			imwrite(name,ROI);
		}
	}
	imshow("輪廓和正外接矩形", copyImg);
	waitKey(0);
	return 0;
}

運行結果:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章