如何使用opencv或javacv识别多边形?
我正在做一个项目,使用图像处理技术来识别不同的物体及其长度。我介绍了javaCV和OpenCV中的许多示例。但不幸的是,我无法识别多边形的T形 我尝试使用以下矩形标识方法,但失败了如何使用opencv或javacv识别多边形?,java,c++,opencv,javacv,Java,C++,Opencv,Javacv,我正在做一个项目,使用图像处理技术来识别不同的物体及其长度。我介绍了javaCV和OpenCV中的许多示例。但不幸的是,我无法识别多边形的T形 我尝试使用以下矩形标识方法,但失败了 public static CvSeq findSquares( final IplImage src, CvMemStorage storage) { CvSeq squares = new CvContour(); squares = cvCreateSeq(0, sizeof(CvContour.class
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;
}
public static CvSeq findSquares(最终IplImage src,CvMemStorage)
{
CvSeq squares=新的CvContour();
正方形=cvCreateSeq(0,sizeof(CvContour.class),sizeof(CvSeq.class),存储);
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());
//缩小和放大图像以滤除噪声
cvPyrDown(timg、pyr、CV_GAUSSIAN_5x5);
cvPyrUp(pyr、timg、CV_GAUSSIAN_5x5);
cvSaveImage(“ha.jpg”,timg);
CvSeq轮廓=新的CvContour();
//图像窗口关闭时请求关闭应用程序
//在窗口上显示图像
//在图像的每个颜色平面中查找正方形
对于(int c=0;c<3;C++)
{
IplImage通道[]={cvCreateImage(sz,8,1),cvCreateImage(sz,8,1),cvCreateImage(sz,8,1)};
通道[c]=cvCreateImage(sz,8,1);
如果(src.nChannels()>1){
cvSplit(timg,通道[0],通道[1],通道[2],空);
}否则{
tgray=cvCloneImage(timg);
}
tgray=通道[c];
//尝试几个阈值级别
对于(int l=0;l0){
近似=cvApproxPoly(轮廓、装载机尺寸(CvContour.class)、存储、CV_POLY_近似_DP、CvContour周长(轮廓)*0.02,0);
如果(大约总计()==4
&&
数学绝对值(CV轮廓面积(约,CV_整,0))>1000&&
Cv凸度(近似值)!=0
){
双最大余弦=0;
//
对于(int j=2;j<5;j++)
{
//求关节边之间角度的最大余弦
双余弦=数学绝对值(角度(新cvGetSeqElem(约,j%4)),新cvGetSeqElem(约,j-2)),新cvGetSeqElem(约,j-1));
maxCosine=Math.max(maxCosine,cosine);
}
如果(最大余弦<0.2){
CvRect x=cvBoundingRect(近似值,l);
如果((x.thth.*)*xHead())<> >你可能会更好地找到等值线,使用<代码> cvAxxPixor()/Cube >。你可以找到一个很好的例子,说明如何使用这个函数来查找矩形并使它适应你的T形。这个例子是用OpenCV创建的,用C++编写。
要按顺序遍历所有点,请执行以下操作:
for (int i = 0; i < cornerPoints->total; i++) {
CvPoint *cornerPoints = (CvPoint*) cvGetSeqElem(cornerPoints, i);
}
for(int i=0;itotal;i++){
CvPoint*cornerPoints=(CvPoint*)cvgetsekelem(cornerPoints,i);
}
我找到了解决您问题的方法:
- 将图像转换为灰度:
- 执行阈值设置(转换为1比特图像):
- 找到等高线并填充它们:
提示:要在OpenCV中填充轮廓,请使用-1
作为drawContours
函数中的thickness
参数
- 进行膨胀,并在腐蚀后使用相同的内核:
就这样!在这之后,在图像上找到你的T形状的图形对你来说不是问题
不幸的是,我不知道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);
Mat src=imread(“in.jpg”),灰色;
CVT颜色(src、灰色、CV_BGr2灰色);
阈值(灰色、灰色、230、255、阈值二值化);
向量层次;
矢量等值线;
findContours(灰色、等高线、层次结构、CV_RETR_列表、CV_CHAIN_近似_SIMPLE);
灰色=标量::全部(255);
对于(size_t i=0;i听起来像是家庭作业
@Astor带来的预处理肯定是有帮助的。
但我仍然认为这种形状识别与图像处理有着紧密的联系:形态学
你可以准备一个T形模板,然后“卷曲?”带有预处理结果的模板。我记不起更多详细信息,只需调查标记形态和卷积您需要识别此图像的哪一部分?我已更新了问题,现在它包含有关它的详细信息。因此,我如何访问此类型多边形的长度?@LBNCons首先您必须识别此多边形。有很多方法可以做到这一点。在检测到多边形后,不只是使用approxP