OpenCV - 按照宽度和高度过滤blob [英] OpenCV - Filter blobs by width and height

查看:259
本文介绍了OpenCV - 按照宽度和高度过滤blob的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由canny边缘检测器过滤的图像。现在,我想检测blob,并做一些过滤器的宽度和高度。

  #includeopencv2 / imgproc.hpp
#includeopencv2 / highgui.hpp

using namespace cv;
using namespace std;

//!计算两点之间的距离
/ *!计算两点之间的欧几里得距离
*
* @param a Point a
* @param b Point b
* /
static double distanceBtwPoints(const cv :: Point2f& a,const cv :: Point2f& b)
{
double xDiff = ax -bx;
double yDiff = a.y - b.y;

return std :: sqrt((xDiff * xDiff)+(yDiff * yDiff));
}

int main(int argc,char ** argv)
{
Mat src,gray;
src = imread(argv [1]);
if(src.empty())
return -1;

cvtColor(src,gray,COLOR_BGR2GRAY);
gray = 200;

vector< vector< Point> >轮廓;

findContours(gray.clone(),contoururs,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);

RotatedRect _minAreaRect;

for(size_t i = 0; i {
_minAreaRect = minAreaRect(Mat(contoururs [i]))
Point2f pts [4];
_minAreaRect.points(pts);

double dist0 = distanceBtw Pointss(pts [0],pts [1]);
double dist1 = distanceBtwPoints(pts [1],pts [2]);

double angle = 0;
if(dist0> dist1 * 4)
angle = atan2(pts [0] .y - pts [1] .y,pts [0] .x - pts [1] .x)* 180.0 / CV_PI;
if(dist1> dist0 * 4)
angle = atan2(pts [1] .y - pts [2] .y,pts [1] .x - pts [2] .x)* 180.0 / CV_PI;

if(fabs(angle)> 35& fabs(angle)< 150)
for(int j = 0; j <4; j ++)
line (src,pts [j],pts [(j + 1)%4],Scalar(0,0,255),1,LINE_AA);
}
imshow(result,src);
waitKey(0);
return 0;
}


I have a image filtered by canny edge detector. Now, i want to detect blobs and do some filter by width and height. What are the functions that i have to look at ?

解决方案

an alternative approach based on minAreaRect of contours and distance between minAreaRect points. by this way it is possible to filter contours by their angles as seen on sample result image.

you can change width & height ratio and angel by changing following lines

if(dist0 > dist1 *4) // dist0 and dist1 means width and height you can change as you wish
.
.
if( fabs(angle) > 35 & fabs(angle) < 150 ) // you can change angle criteria

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"

using namespace cv;
using namespace std;

//! Compute the distance between two points
/*! Compute the Euclidean distance between two points
*
* @param a Point a
* @param b Point b
*/
static double distanceBtwPoints(const cv::Point2f &a, const cv::Point2f &b)
{
    double xDiff = a.x - b.x;
    double yDiff = a.y - b.y;

    return std::sqrt((xDiff * xDiff) + (yDiff * yDiff));
}

int main( int argc, char** argv )
{
    Mat src,gray;
    src = imread(argv[1]);
    if(src.empty())
        return -1;

    cvtColor( src, gray, COLOR_BGR2GRAY );
    gray = gray < 200;

    vector<vector<Point> > contours;

    findContours(gray.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

    RotatedRect _minAreaRect;

    for (size_t i = 0; i < contours.size(); ++i)
    {
        _minAreaRect = minAreaRect( Mat(contours[i]) );
        Point2f pts[4];
        _minAreaRect.points(pts);

        double dist0 = distanceBtwPoints(pts[0], pts[1]);
        double dist1 = distanceBtwPoints(pts[1], pts[2]);

        double angle = 0;
        if(dist0 > dist1 *4)
            angle =atan2(pts[0].y - pts[1].y,pts[0].x - pts[1].x) * 180.0 / CV_PI;
        if(dist1 > dist0 *4)
            angle =atan2(pts[1].y - pts[2].y,pts[1].x - pts[2].x) * 180.0 / CV_PI;

        if( fabs(angle) > 35 & fabs(angle) < 150 )
            for( int j = 0; j < 4; j++ )
                line(src, pts[j], pts[(j+1)%4], Scalar(0, 0, 255), 1, LINE_AA);
    }
    imshow("result", src);
    waitKey(0);
    return 0;
}

这篇关于OpenCV - 按照宽度和高度过滤blob的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆