1. ホーム
  2. OpenCV

OpenCV23 はオブジェクトの周囲に楕円や矩形を描画する_outline

2022-03-16 06:21:57

/* OpenCV23 は,オブジェクト上の輪郭を囲む矩形と楕円を描画します.



by txwtech





アウトラインの周りに矩形を描く -API





approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)

RDPアルゴリズムに基づき、ポリゴン輪郭の点数を減らすことを目的とする

cv::boundingRect(InputArray points)

輪郭を囲む最小の矩形の左上交点と右下隅点の座標を取得し、矩形を描画する





cv::minAreaRect(InputArray points)

回転した矩形を取得し、回転した矩形を返す

アウトラインの周りに円や楕円を描く - API



cv::minEnclosingCircle(InputArray points, //最小面積の円を取得します.



Point2f& center, // 円の中心の位置



float& radius)// 円の半径を指定します。



cv::fitEllipse(InputArray points) で,最小の楕円を求めます.

実装の流れです。





1. 画像を2値画像にする



2. アウトラインを発見する、画像のアウトラインを発見する



3. 3. 矩形と円を含む最小値を求め、その輪郭点上で矩形と楕円を関連する API により回転させる。



4. 引き出し





---------------------------



Microsoft Visual C++ ランタイムライブラリ



---------------------------



デバッグアサーションに失敗しました

プログラム C:\windowsSYSTEM32 ↵MSVCP140D.dll



File: c:\program files (x86)\microsoft visual studio 14.0vcinclude



行数:1234

式: ベクトル添え字が範囲外です

あなたのプログラムがどのようにアサーションを引き起こすかについては



の失敗については、Visual C++のアサートに関するドキュメントを参照してください。

(アプリケーションをデバッグするにはRetryを押してください)

---------------------------



中止(A) 再試行(R) 無視(I)



---------------------------



vector<vector<Point>> contours_ploy();//初期値が割り当てられず、エラーとなる。

vector<vector<Point>> contours_ploy(contours.size());/This is Ok

*/

#include <iostream>
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;

Mat src;
Mat src_gray;
Mat draw_image;
int threshold_min = 90;
int threshold_max = 255;
const char* out_window = "Rectangle output result";
RNG rng(12345);
void Contours_Func(int, void*);
int main(int argc, char *argv[])
{
	src = imread("e:\\pictures\\\ hot air balloon.jpg",CV_LOAD_IMAGE_COLOR);
	if (!src.data)
	{
		printf("failed to load image");
		return -1;
	}
	//namedWindow("original",CV_WINDOW_AUTOSIZE);
	//imshow("original",src);
	//transform grayscale image
	cvtColor(src, src_gray, CV_BGR2GRAY);
	//blur
	blur(src_gray,src_gray,Size(3,3),Point(-1,-1));
	const char* src_window = "original";
	namedWindow(src_window,CV_WINDOW_AUTOSIZE);
	namedWindow(out_window,CV_WINDOW_AUTOSIZE);
	imshow(src_window,src);

	createTrackbar("threshold:",out_window,&threshold_min,threshold_max,Contours_Func);

	Contours_Func(0,0);
	waitKey(0);
	
	return 0;
}
void Contours_Func(int, void*)
{
	Mat binary_output;//binary image
	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	//threshold processing
	threshold(src_gray,binary_output,threshold_min,threshold_max,THRESH_BINARY);
	//find contours
	findContours(binary_output,contours,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(-1,-1));
    
	vector<vector<Point>> contours_ploy(contours.size());//external polygon
	//find the smallest rectangle
	vector<Rect> ploy_rects(contours.size());;
	vector<Point2f> ccs(contours.size());//center of circle
	vector<float> radius(contours.size());//radius

	vector<RotatedRect> minRect(contents.size());
	vector<RotatedRect> myellipse(contents.size());
	for (size_t i = 0; i < contours.size(); i++)
	{
		//true means draw closed rectangle
		approxPolyDP(Mat(contours[i]),contours_ploy[i],3,true);
		ploy_rects[i] = boundingRect(contours_ploy[i]);
		minEnclosingCircle(contours_ploy[i],ccs[i],radius[i]);

		if (contours_ploy[i].size() > 5)
		{
		myellipse[i] = fitEllipse(contours_ploy[i]);
		minRect[i] = minAreaRect(contents_ploy[i]);
					
		}

	}
	//src.copyTo(draw_image);//draw ellipse and rectangle on original image
	draw_image = Mat::zeros(src.size(),src.type());//this sentence is to draw on a blank template
	Point2f pts[4];

	for (size_t t = 0; t < contours.size(); t++)
	{
		Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0, 255), rng.uniform(0, 255));
		//rectangle(draw_image,ploy_rects[t],color,2,8);
		//circle(draw_image,ccs[t],radius[t],color,2,8);

		if (contours_ploy[t].size() > 5)
		{ 
			//draw ellipse
		ellipse(draw_image,myellipse[t],color,1,8);
		minRect[t].points(pts);

		// draw 4 lines is a rectangle
		for (int r = 0; r < 4; r++)
		{
			line(draw_image,pts[r],pts[(r+1)%4],color,1,8);
		}
		}
	}
	//imshow(out_window, draw_image);//normal display
	imshow(out_window,~draw_image);//reverse color display
		
}