// selectshape.cpp : 选择轮廓
// by: jsxyhelu(1755311380)
#
include
"stdafx.h"
#
include
<iostream
>
#
include
"opencv2/core/core.hpp"
#
include
"opencv2/highgui/highgui.hpp"
#
include
"opencv2/imgproc/imgproc.hpp"
using
namespace std;
using
namespace cv;
#
define VP vector
<Point
>
//用VP符号代替 vector<point>
RNG rng(
12345 );
//带有上下限的threshold
void threshold2(Mat gray,Mat
& thresh,
int minvalue,
int maxvalue)
{
Mat thresh1;
Mat thresh2;
threshold(gray,thresh1,
43,
255, THRESH_BINARY);
threshold(gray,thresh2,
111,
255,THRESH_BINARY_INV);
thresh
= thresh1
& thresh2;
}
//寻找并绘制出联通区域
vector
<VP
> connection2(Mat src,Mat
& draw)
{
draw
= Mat
:
:zeros(src.rows,src.cols,CV_8UC3);
vector
<VP
>contours;
findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
for (
int i
=
0;i
<contours.size();i
++)
{
Scalar color
= Scalar(rng.uniform(
0,
255),rng.uniform(
0,
255),rng.uniform(
0,
255));
drawContours(draw,contours,i,color,
-
1);
}
return contours;
}
//select_shape
vector
<VP
> selectShapeArea(Mat src,Mat
& draw,vector
<VP
> contours,
int minvalue,
int maxvalue)
{
vector
<VP
> result_contours;
draw
= Mat
:
:zeros(src.rows,src.cols,CV_8UC3);
for (
int i
=
0;i
<contours.size();i
++)
{
int countour_area
= contourArea(contours[i]);
if (countour_area
>minvalue
&& countour_area
<maxvalue)
{
result_contours.push_back(contours[i]);
}
}
for (
int i
=
0;i
<result_contours.size();i
++)
{
Scalar color
= Scalar(rng.uniform(
0,
255),rng.uniform(
0,
255),rng.uniform(
0,
255));
drawContours(draw,result_contours,i,color,
-
1);
}
return result_contours;
}
//计算轮廓的圆的特性
float calculateCircularity(VP contour)
{
Point2f center;
float radius
=
0;
minEnclosingCircle((Mat)contour,center,radius);
//以最小外接圆半径作为数学期望,计算轮廓上各点到圆心距离的标准差
float fsum
=
0;
float fcompare
=
0;
for (
int i
=
0;i
<contour.size();i
++)
{
Point2f ptmp
= contour[i];
float fdistenct
= sqrt((
float)((ptmp.x
- center.x)
*(ptmp.x
- center.x)
+(ptmp.y
- center.y)
*(ptmp.y
-center.y)));
float fdiff
= abs(fdistenct
- radius);
fsum
= fsum
+ fdiff;
}
fcompare
= fsum
/(
float)contour.size();
return fcompare;
}
//select_shape
vector
<VP
> selectShapeCircularity(Mat src,Mat
& draw,vector
<VP
> contours,
float minvalue,
float maxvalue)
{
vector
<VP
> result_contours;
draw
= Mat
:
:zeros(src.rows,src.cols,CV_8UC3);
for (
int i
=
0;i
<contours.size();i
++)
{
float fcompare
= calculateCircularity(contours[i]);
if (fcompare
>
=minvalue
&& fcompare
<
=maxvalue)
{
result_contours.push_back(contours[i]);
}
}
for (
int i
=
0;i
<result_contours.size();i
++)
{
Scalar color
= Scalar(rng.uniform(
0,
255),rng.uniform(
0,
255),rng.uniform(
0,
255));
drawContours(draw,result_contours,i,color,
-
1);
}
return result_contours;
}
int _tmain(
int argc, _TCHAR
* argv[])
{
Mat src;
Mat gray;
Mat thresh;
Mat draw_connection;
Mat draw_area;
Mat draw_circle;
vector
<VP
>contours_connection;
vector
<VP
>contours_area;
vector
<VP
>contours_circle;
vector
<VP
>contours_tmp;
//read_image (Image1, 'F:/未来项目/钢管识别/FindTube/FindTube/1.jpg')
src
= imread(
"1.jpg");
//rgb1_to_gray (Image1, GrayImage)
cvtColor(src,gray,COLOR_BGR2GRAY);
//threshold (GrayImage, Regions, 43, 111)
threshold2(gray,thresh,
43,
111);
//connection (Regions, ConnectedRegions)
contours_connection
= connection2(thresh.clone(),draw_connection);
//select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 150, 666)
contours_area
= selectShapeArea(thresh.clone(),draw_area,contours_connection,
150,
666);
//select_shape (SelectedRegions, SelectedRegions1, 'circularity', 'and', 0.45, 1)
contours_circle
= selectShapeCircularity(thresh.clone(),draw_circle,contours_area,
1,
6);
//显示结果
imshow(
"src",src);
imshow(
"thresh",thresh);
imshow(
"draw_connection",draw_connection);
imshow(
"draw_area",draw_area);
imshow(
"draw_circle",draw_circle);
waitKey();
}