Android + OpenCV - Finding extreme points in contours

时间:2022-12-25 12:57:48

原文链接:​​http://answers.opencv.org/question/134783/android-opencv-finding-extreme-points-in-contours/​


导    读本例子使用轮廓分析,寻找到轮廓的极点;使用了STD的SORT特性。



 



提出问题

Good Evening,

I have a trouble with finding extreme points in frames. I am detecting all contours, but I want find there one extreme point, which is lowest from others (southernmost contour). Here is a preview of screen, what I have.

Android + OpenCV - Finding extreme points in contours

And here is a preview of screen, what I want ! For example, lowest point will bounded by red rectangle.

Android + OpenCV - Finding extreme points in contours

.

And here is my code, what I have now.


contours
=
new ArrayList <MatOfPoint
>();

Rect rect;
Point c1 =
new Point(); Point c2 =
new Point();

Imgproc.cvtColor(mRgba, mGray, Imgproc.COLOR_RGB2GRAY);
subtractorMOG2.apply(mGray, mFGMask, 0.
005);


Imgproc.threshold(mFGMask, mFGMask, 45,
255, Imgproc.THRESH_BINARY);

Imgproc.erode(mFGMask, mFGMask, new Mat());
Imgproc.dilate(mFGMask, mFGMask, new Mat());

Imgproc.findContours(mFGMask, contours, new Mat(), Imgproc.RETR_EXTERNAL , Imgproc.CHAIN_APPROX_NONE);
Imgproc.drawContours(mRgba, contours, -
1,
new Scalar( 255,
255,
0),
3);


/*for (int idx = 0; idx < contours.size(); idx++) {

double contourarea = Imgproc.contourArea(contours.get(idx));
rect = boundingRect(contours.get(idx));

c1.x = rect.x; c1.y = rect.y;
c2.x = rect.x + rect.width; c2.y = rect.y + rect.height;
if (contourarea > 1024 && contourarea < 30000) {
Imgproc.rectangle(mRgba, c1, c2, new Scalar(255, 0, 0), 3);
}
}*/

return mRgba;
Thanks everybody for help and comments !


 优质解答:   


 


bool
SortbyXaxis(
const
Point
&
a,
const
Point
&
b)

{
return a.x > b.x;

}
bool SortbyYaxis( const Point & a,
const Point &b)

{
return a.y > b.y;

}
int main ( int argc, char *
const argv[])
{
Mat mSrc,mDst;
mSrc = imread(
"e:/sandbox/aline.png",
0);

if (mSrc.empty())
{
cerr <<
"No image supplied ..."
<< endl;

return -
1;

}
cvtColor(mSrc,mDst,COLOR_GRAY2BGR);
/// Create Window

const char
* source_window
=
"Output Image";

namedWindow( source_window, WINDOW_AUTOSIZE );
vector <vector
<Point
>
> contours;

vector <Vec4i
> hierarchy;

/// Find contours

findContours( mSrc.clone(), contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point( 0,
0) );

vector <Point
> ptsContour;

for( size_t i =
0; i
< contours.size(); i
++ )

{
drawContours( mDst, contours, ( int)i, Scalar( 0,
255,
0),
1);

ptsContour = contours[i];

sort( ptsContour.begin(), ptsContour.end(), SortbyYaxis );
sort( ptsContour.begin(), ptsContour.end(), SortbyXaxis );
circle(mDst, ptsContour[ 0],
3,Scalar(
0,
255,
255),
-
1);

}
imshow( source_window, mDst );
waitKey();
return 0;

}


Android + OpenCV - Finding extreme points in contours


 


Android + OpenCV - Finding extreme points in contours


 程序解读本程序的基本思路是很简答的,就是遍历轮廓,找到轮廓中x和y最大的点,这个点就是极值点。但是有两个地方需要注意:


1、是使用了std的sort特性,应该说简化了程序设计;


2、是findcontours的第二个参数,使用的是“只寻找第一层轮廓”。那么对于本例来说,这样做是合理的。