opencv rect dection

#include <opencv2\opencv.hpp>
#include <iostream>
#include <vector>
#include <cmath>


using namespace cv;
using namespace std;
const int N = 50;
const char* wn2dName = "DetectSquares";  //窗口名字

                                         //angle返回一个角的余弦(cos);
                                         //pt1,pt2,pt0为确定这个角的三个点,pt0为顶点;
double ang2le(Point pt1, Point pt2, Point pt0)
{
    double dx1 = pt1.x - pt0.x;
    double dy1 = pt1.y - pt0.y;

    double dx2 = pt2.x - pt0.x;
    double dy2 = pt2.y - pt0.y;

    double cosine = (dx1*dx2 + dy1*dy2) / (sqrt(dx1*dx1 + dy1*dy1) * sqrt(dx2*dx2 + dy2*dy2) + 1e-10);

    return cosine;
}


void finxdSquares(Mat& img, vector<vector<Point>>& squares)
{
    squares.clear();

    Mat blurImg(img);
    medianBlur(img, blurImg, 9);      //中值滤波

    Mat gray0(blurImg.size(), CV_8U), gray;

    vector<vector<Point>> contours;

    for (int c = 0; c < 3; c++)        //每次处理一个通道
    {
        int channels[] = { c,0 };
        mixChannels(&blurImg, 1, &gray0, 1, channels, 1);   //提取一个通道到gray0

        for (int l = 0; l < N; l++)            //选取阈值
        {
            if (l == 0)                        //l=0时,利用Canny滤波得到二值化图像
            {
                Canny(gray0, gray, 5, 50, 5);

                dilate(gray, gray, Mat());
            }
            else
            {
                gray = gray0 >= (l + 1) * 255 / N;
            }

            findContours(gray, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);


            vector<Point> approx;

            for (size_t i = 0; i < contours.size(); i++)  //从所有的轮廓中找出接近矩形的
            {
                approxPolyDP(contours[i], approx, arcLength(contours[i], true)*0.02, true);

                if (approx.size() == 4 &&
                    fabs(contourArea(approx)) >= 1000 &&
                    isContourConvex(approx))
                {
                    double maxCosine = 0;

                    for (int j = 2; j < 5; j++)
                    {
                        double cosine = fabs(ang2le(approx[j % 4], approx[j - 2], approx[j - 1]));
                        maxCosine = MAX(maxCosine, cosine);
                    }
                    if (maxCosine <= 0.3)             //直角的矩形应该为0
                        squares.push_back(approx);

                }

            }

        }

    }


}


//画出检测到的矩形物体
void drawxSquares(Mat& img, vector<vector<Point>>& squares)
{
    polylines(img, squares, true, Scalar(0, 255, 0), 3, LINE_AA);
    /*
    for (size_t i = 0; i < squares.size(); i++)
    {
    Point* pts = &squares[i][0];
    int npt = squares[i].size();
    polylines(img, &pts, &npt, 1, true, Scalar(0, 255, 0), 3, LINE_AA);

    }
    */
    imshow(wn2dName, img);
}
int pos_x1 = 0;
int pos_y1 = 0;
int pos_x2 = 0;
int pos_y2 = 0;
int flag = 0;

static void onMouse(int event, int x, int y, int, void*)
{
    if (event == EVENT_LBUTTONDOWN || event == EVENT_MOUSEMOVE || event == EVENT_RBUTTONDOWN)
    {
        return;
    }
    if (flag == 0)
    {
        pos_x1 = x;
        pos_y1 = y;
        flag = 1;
    }
    if (flag == 1)
    {
        pos_x2 = x;
        pos_y2 = y;
        flag = 2;
    }

    cout << "user mounse position " << x << ": " << y << endl;
}

Mat  dratest(Mat mat) {

    int  cols = mat.cols;
    int  rows = mat.rows;
    Mat  src = Mat::zeros(mat.size(), CV_8UC1);
    for (size_t i = 0; i < cols; i++)
    {
        for (size_t j = 0; j < rows; j++)
        {
            uchar  a = mat.at<uchar>(j, i);
            if (a != 0) {
                uchar  b = mat.at<uchar>(j - 1, i);
                uchar  c = mat.at<uchar>(j + 1, i);
                if (b == 0 && c != 0) {
                    src.at<uchar>(j, i) = 255;
                }
            }
        }
    }
    vector<Point>  pos;
    findNonZero(src, pos);
    cout << "PS" << pos << endl;
    for (size_t i = 0; i < pos.size(); i++)
    {

    }
    return  src;

}

void  getFirstPoint(Mat&  mat) {
    int  rows = mat.rows;
    int  cols = mat.cols;
    int  minx = 0;
    int  miny = 0;
    Point  p;
    for (size_t j = 0; j < cols; j++)
    {
        for (size_t i = 0; i < rows; i++)
        {

            uchar  a = mat.at<uchar>(i, j);
            if (a != 0) {
                p = Point(j, i);
                break;
            }
        }
    }
    int  a = mat.at<uchar>(404, 352);
    cout << a << endl;
    cout << "Point" << p.x << "y" << p.y << endl;

    circle(mat, p, 5, Scalar(255), 10);

}
void  getPointyMin(vector<Point> po, Point  &p) {
    cout << "poSIZE" << po.size() << endl;

    for (size_t i = 0; i < po.size(); i++)
    {
        //    cout << "POX" << po[i].x << "POY" << po[i].y << endl;
        if (po[i].y < p.y) {
            p = po[i];
        }
    }
}
void  getPointAll(vector<Vec4i>lines, Mat cdst1) {
    for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i l = lines[i];
        Point p1(l[0], l[1]);
        Point p2(l[2], l[3]);
        float  k = 1.0f*(p2.y - p1.y) / (p2.x - p1.x);
        cout << p1.x << "p1y" << p1.y << "p2" << p2.x << "p2y" << p2.y << "K" << k << endl;
        if (k >= 0 && k<1) {
            line(cdst1, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255), 1, CV_AA);
        }
        for (size_t j = 0; j < lines.size(); j++)
        {

            if (j != i) {
                float  k2 = 1.0f*(p2.y - p1.y) / (p2.x - p1.x);

            }
        }

    }
}
//2点距离
float getLinedistance(Point p1, Point p2) {

    return  sqrt(pow((p2.y - p1.y), 2) + pow((p2.x - p1.x), 2));
}


//直线交点
Vec2i  intersectionLines(Vec4i v1, Vec4i v2) {
    float  k1 = 1.0f*(v1[3] - v1[1]) / (v1[2]- v1[0]);
    float  b1 =v1[1]- 1.0f*v1[0]*k1;
    float  k2 = 1.0f*(v2[3] - v2[1]) / (v2[2] - v2[0]);
    float  b2 = v2[1] - 1.0f*v2[0] * k2;
    float  x = (b1 - b2) / (k2 - k1);
    float  y = x*k1 + b1;
    int  xi = (int)(x + 0.5);
    int  yi = (int)(y + 0.5);

    return  Vec2i(x,y);

}
// 4点是否满足距离很近
Vec2i  fourPointNear(Vec4i v1, Vec4i v2) {
    Point p1(v1[0], v1[1]);
    Point p2(v1[2], v1[3]);
    Point p3(v2[0], v2[1]);
    Point p4(v2[2], v2[3]);
    float  a1 = getLinedistance(p1, p3);
    float  a2 = getLinedistance(p1, p4);
    float  a3 = getLinedistance(p2, p3);
    float  a4 = getLinedistance(p2, p4);
    cout << a1 << "a2==" << a2 << "a3===" << a3 << "a4===" << a4 << endl;
    float thresholdValue = 60;
    if (a1 < 60 || a2 < 60 || a3 < 60 || a4 < 60) {
        return  intersectionLines(v1,v2);
    }else {
        
    }
    return NULL;
}
//去掉重复点
void eraseRepeatPoint(vector<Vec4i> &lines) {
    vector<Vec4i>  addv;
    for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i  vs = lines[i];
        bool  ishas = false;
        for (Vec4i dx : addv) {
            if (vs == dx) {
                ishas = true;
          }
        }
        if (ishas == false) {
            addv.push_back(vs);
        }

    }
    lines = addv;
}
//6点排序
void  sexSort(vector<Vec2i> &vecs) {
    vector<Vec2i> ves;
    int  sum = vecs.size();
    while (sum>0)
    {
        cout << "sum"<<sum << endl;
        Vec2i  vv (0,9999);
        int  p = 0;
        for (size_t i = 0; i < sum; i++)
        {
            Vec2i  v2 = vecs[i];
            if (v2[1] < vv[1]) {
                vv = v2;
                p = i;
            }
        }
        ves.push_back(vv);
        vecs.erase(vecs.begin() + p);
        sum = vecs.size();
        
    }
    vecs = ves;
    
}
//获取交点
void  getInterSectionPoint(vector<Vec4i> lines,vector<Vec2i>  &vecs) {

    for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i  l1 = lines[i];
    
        for (size_t j = 0; j < lines.size(); j++)
        {
            if (i != j) {
                Vec4i  l2 = lines[j];
                Vec2i v2f = fourPointNear(l1, l2);
                if (v2f[0] != 0) {
                    //cout << v2f << "-----------" << endl;
                    vecs.push_back(v2f);
                }
            }

        }
    }
    vector<Vec2i>  eraseValue;
    for (size_t i = 0; i < vecs.size(); i++)
    {
        Vec2i  vs = vecs[i];
        bool  ishas = false;
        for (Vec2i dx : eraseValue) {
            if (vs == dx) {
                ishas = true;
            }
        }
        if (ishas == false) {
            eraseValue.push_back(vs);
        }

    }
    sexSort(eraseValue);
    vecs = eraseValue;

}

int main()
{

    cv::Mat image = cv::imread("x4.jpg");
    int  h = image.rows / 5;
    int  w = image.cols / 5;
    resize(image, image, Size(w, h));
    cout << image.rows << "COLS" << image.cols << endl;
    if (!image.data)
    {
        cout << "不能打开图像!" << endl;
        return 0;
    }
    // 矩形外的像素是背景
    cv::Rect rectangle(45, 199, 310, 460);
//    cv::Rect rectangle(92, 13, 700, 500);
    namedWindow("callback");
    setMouseCallback("callback", onMouse);
    imshow("callback", image);
    cv::Mat result;
    //两个临时矩阵变量,作为算法的中间变量使用,不用care
    cv::Mat bgModel, fgModel;
    double tt = cv::getTickCount();
    // GrabCut 分段
    cv::grabCut(image,    //输入图像
        result,   //分段结果
        rectangle,// 包含前景的矩形
        bgModel, fgModel, // 前景、背景
        3,        // 迭代次数
        cv::GC_INIT_WITH_RECT); // 用矩形
    tt = cv::getTickCount() - tt;
    printf("算法执行执行时间:%g ms\n", tt / cv::getTickFrequency() * 1000);
    // 得到可能是前景的像素
    //比较函数保留值为GC_PR_FGD的像素
    cv::compare(result, cv::GC_PR_FGD, result, cv::CMP_EQ);
    //Mat  foreground;
    // 产生输出图像
    cv::Mat foreground(image.size(), CV_8UC3, cv::Scalar(0, 0, 0));
    //背景值为 GC_BGD=0,作为掩码
    image.copyTo(foreground, result);
    Mat  gray;
    vector<Point> vas;
    cvtColor(foreground, gray, CV_BGR2GRAY);
    Mat msrc(image.size(), CV_8UC1, cv::Scalar(0));
    findNonZero(gray, vas);
    int  a = 0;
    for (size_t i = 0; i < vas.size(); i++)
    {
        if (i > 1) {
            int  ax = vas[i].x;
            int  aux = vas[i - 1].x;
            int  adx = vas[i + 1].x;

        }
        msrc.at<uchar>(vas[i].y, vas[i].x) = 255;
    }
    imshow("msrc", msrc);
    Mat  laps;
    vector<Point> lapspoint;
    Laplacian(msrc, laps, CV_16S);
    convertScaleAbs(laps, laps);
    findNonZero(laps, lapspoint);
    Point p(0, 999);
    getPointyMin(lapspoint, p);
    cout << "P" << p.y << endl;
    circle(laps, p, 10, Scalar(100), 10);
    Mat  dst = Mat::zeros(laps.size(), laps.type());
    vector<Point2f> corners;
    int maxCorners = 5;
    double qualityLevel = 0.05;
    double minDistance = 50;
    int blockSize = 20;
    bool useHarrisDetector = false;
    double k = 0.02;
    goodFeaturesToTrack(laps, corners, maxCorners, qualityLevel, minDistance, Mat(), blockSize, useHarrisDetector, k);
    int r = 4;
    for (int i = 0; i < corners.size(); i++)
    {
        circle(gray, corners[i], r, Scalar(255), 10);

    }
    imshow("laps", laps);
    vector<Vec4i> lines;
    vector<Vec4i> addlines;
    HoughLinesP(laps, lines, 1, CV_PI / 180, 50, 50, 10);
    Mat cdst1 = Mat::zeros(laps.size(), laps.type());
    Mat cdst2 = Mat::zeros(laps.size(), laps.type());
    for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i l = lines[i];
        Point p1(l[0], l[1]);
        Point p2(l[2], l[3]);
        float  k = 1.0f*(p2.y - p1.y) / (p2.x - p1.x);
        float  b = p1.y - 1.0f*p1.x*k;
        cout << p1.x << "p1y" << p1.y << "p2" << p2.x << "p2y" << p2.y << "K=" << k << "B=" << b << endl;
    
        line(cdst2, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255), 1, CV_AA);
        for (size_t j = 0; j < lines.size(); j++)
        {
            if (j != i) {
                Vec4i l2 = lines[j];
                Point p3(l2[0], l2[1]);
                Point p4(l2[2], l2[3]);
                float  k2 = 1.0f*(p4.y - p3.y) / (p4.x - p3.x);
                float k3 = abs(k2 - k);
                float  b2 = p3.y - 1.0f*p3.x*k;
                float  b3 = abs(b2 - b);
                float  bd = abs(b2)*0.2;
                    if (k3 < 0.5&&b3<bd) {
                    int ax = min(p1.x, p3.x);
                    int ay = 0;
                    if (p1.x == p3.x) {
                        if (k2 > 0)
                            ay = max(p1.y, p3.y);
                        else     ay = min(p1.y, p3.y);
                    }
                    else {
                        if (ax == p3.x)
                            ay = p3.y;
                        else {
                            ay = p1.y;
                        }
                    }
                    
                    int bx = max(p2.x, p4.x);
                    int by = 0;
                    if (p2.x == p4.x) {
                        if (k2 > 0)
                            by = min(p2.y, p4.y);
                        else     by = max(p2.y, p4.y);
                    }
                    else {
                        if (bx == p2.x)
                            by = p2.y;
                        else {
                            by = p4.y;
                        }
                    }
                
                    p1.x = ax;
                    p1.y = ay;
                    p2.x = bx;
                    p2.y = by;
                    }
            }
    
            
            
            
        }
        addlines.push_back(Vec4i(p1.x, p1.y, p2.x, p2.y));

    }
    cout << addlines.size() << "SIZEADDLINES" << endl;
    eraseRepeatPoint(addlines);
    vector<Vec2i>  vec2fs;
    getInterSectionPoint(addlines, vec2fs);
    cout << "Vec2f"<< vec2fs.size() << endl;
    for (size_t i = 0; i < vec2fs.size(); i++)
    {
        Vec2f  v2f = vec2fs[i];
        cout << v2f << endl;
        circle(cdst1, Point(v2f[0], v2f[1]),10, Scalar(255), 1);
    }
    cout << addlines.size()<<"SIZEADDLINES" << endl;
    for (size_t i = 0; i < addlines.size(); i++)
    {
        Vec4i l = addlines[i];
        Point p1(l[0], l[1]);
        Point p2(l[2], l[3]);
        float  k = 1.0f*(p2.y - p1.y) / (p2.x - p1.x);
        float  b = p1.y - 1.0f*p1.x*k;

        cout << p1.x << "p1y" << p1.y << "p2" << p2.x << "p2y" << p2.y << "K=" << k << "B=" << b << endl;
        line(cdst1, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255), 1, CV_AA);
        
    }
    imshow("cdst1", cdst1);
    imshow("cdst2", cdst2);
    cout << lines.size() << "s" << endl;
    imshow("callback2", foreground);
    imshow("gray", gray);
    waitKey();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值