[英]How to identify polygon using opencv or javacv?
I'm doing a project that use image processing techniques to identify different objects and their lengths. 我正在做一个使用图像处理技术来识别不同对象及其长度的项目。 I go through many examples in javaCV as well as OpenCV. 我在javaCV和OpenCV中经历了很多例子。 But unfortunately I was unable to identify T shape of polygon. 但不幸的是我无法识别多边形的T形。
I try to use following rectangle identification method but I failed it. 我尝试使用以下矩形识别方法,但我失败了。
public static CvSeq findSquares( final IplImage src, CvMemStorage storage)
{
CvSeq squares = new CvContour();
squares = cvCreateSeq(0, sizeof(CvContour.class), sizeof(CvSeq.class), storage);
IplImage pyr = null, timg = null, gray = null, tgray;
timg = cvCloneImage(src);
CvSize sz = cvSize(src.width() & -2, src.height() & -2);
tgray = cvCreateImage(sz, src.depth(), 1);
gray = cvCreateImage(sz, src.depth(), 1);
pyr = cvCreateImage(cvSize(sz.width()/2, sz.height()/2), src.depth(), src.nChannels());
// down-scale and upscale the image to filter out the noise
cvPyrDown(timg, pyr, CV_GAUSSIAN_5x5);
cvPyrUp(pyr, timg, CV_GAUSSIAN_5x5);
cvSaveImage("ha.jpg", timg);
CvSeq contours = new CvContour();
// request closing of the application when the image window is closed
// show image on window
// find squares in every color plane of the image
for( int c = 0; c < 3; c++ )
{
IplImage channels[] = {cvCreateImage(sz, 8, 1), cvCreateImage(sz, 8, 1), cvCreateImage(sz, 8, 1)};
channels[c] = cvCreateImage(sz, 8, 1);
if(src.nChannels() > 1){
cvSplit(timg, channels[0], channels[1], channels[2], null);
}else{
tgray = cvCloneImage(timg);
}
tgray = channels[c];
// try several threshold levels
for( int l = 0; l < N; l++ )
{
// hack: use Canny instead of zero threshold level.
// Canny helps to catch squares with gradient shading
if( l == 0 )
{
// apply Canny. Take the upper threshold from slider
// and set the lower to 0 (which forces edges merging)
cvCanny(tgray, gray, 0, thresh, 5);
// dilate canny output to remove potential
// // holes between edge segments
cvDilate(gray, gray, null, 1);
}
else
{
// apply threshold if l!=0:
cvThreshold(tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY);
}
// find contours and store them all as a list
cvFindContours(gray, storage, contours, sizeof(CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
CvSeq approx;
// test each contour
while (contours != null && !contours.isNull()) {
if (contours.elem_size() > 0) {
approx = cvApproxPoly(contours, Loader.sizeof(CvContour.class),storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0);
if( approx.total() == 4
&&
Math.abs(cvContourArea(approx, CV_WHOLE_SEQ, 0)) > 1000 &&
cvCheckContourConvexity(approx) != 0
){
double maxCosine = 0;
//
for( int j = 2; j < 5; j++ )
{
// find the maximum cosine of the angle between joint edges
double cosine = Math.abs(angle(new CvPoint(cvGetSeqElem(approx, j%4)), new CvPoint(cvGetSeqElem(approx, j-2)), new CvPoint(cvGetSeqElem(approx, j-1))));
maxCosine = Math.max(maxCosine, cosine);
}
if( maxCosine < 0.2 ){
CvRect x=cvBoundingRect(approx, l);
if((x.width()*x.height())<5000 ){
System.out.println("Width : "+x.width()+" Height : "+x.height());
cvSeqPush(squares, approx);
//System.out.println(x);
}
}
}
}
contours = contours.h_next();
}
contours = new CvContour();
}
}
return squares;
}
Please can some help me to modify this method to identify T shapes from a image. 请帮助我修改此方法以识别图像中的T形状。 The input image is like this. 输入图像是这样的。
This is the T shape that I have to identify 这是我要识别的T形
I found solution to your problem: 我找到了解决问题的方法:
Hint: to fill contours in OpenCV use -1
as thickness
parameter in drawContours
function. 提示:要在OpenCV中填充轮廓,请使用-1
作为drawContours
函数中的thickness
参数。
And that's it! 就是这样! After this it is not a problem for you to find your T -shaped figure on the image! 在此之后,您在图像上找到T形图形并不是问题!
Unfortunatelly I don't know JavaCV but I can share with you c++ code: 不幸的是我不知道JavaCV,但我可以与你分享c ++代码:
Mat src = imread("in.jpg"), gray;
cvtColor(src, gray, CV_BGR2GRAY);
threshold(gray, gray, 230, 255, THRESH_BINARY_INV);
vector<Vec4i> hierarchy;
vector<vector<Point> > contours;
findContours(gray, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
gray = Scalar::all(255);
for (size_t i=0; i<contours.size(); i++)
{
drawContours(gray, contours, i, Scalar(0), -1);
}
Mat element = getStructuringElement(MORPH_RECT, Size(2, 2), Point(1, 1));
dilate(gray, gray, element);
erode(gray, gray, element);
imshow("window", gray);
Hint: if you want you can convert this code to JavaCV. 提示:如果您愿意,可以将此代码转换为JavaCV。 To do this read this tutorial . 为此,请阅读本教程 。
You might be better of finding contours and using CvApproxPoly()
. 您最好找到轮廓并使用CvApproxPoly()
。 You can find a good example of how to use this function to find rectangles here and adapt it to find your T shapes. 您可以找到一个很好的示例,说明如何使用此函数在此处查找矩形并调整它以查找T形状。 This example is created using OpenCV and written in c++. 此示例使用OpenCV创建并使用c ++编写。
To go through all the points in a sequence: 要遍历序列中的所有点:
for (int i = 0; i < cornerPoints->total; i++) {
CvPoint *cornerPoints = (CvPoint*) cvGetSeqElem(cornerPoints, i);
}
sounds like homework though 听起来像家庭作业
the pre-processing @Astor bring about is definitely helpful. 预处理@Astor带来的肯定是有帮助的。 but I somewhat still think that this shape recognition is strongly connected with Image Processing: Morphology 但我仍然认为这种形状识别与图像处理:形态学密切相关
you could prepare a template T-shaped and then "convolute?" 你可以准备一个T形的模板,然后“回旋?” the template with the pre-processed result. 具有预处理结果的模板。 I can't remember more details, just survey on TAG Morphology and Convolution 我不记得更多细节,只是关于TAG形态学和卷积的调查
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.