首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >开式CV tic detection /O检测

开式CV tic detection /O检测
EN

Stack Overflow用户
提问于 2016-06-03 17:52:44
回答 2查看 700关注 0票数 1

我制作了一个程序,以制作图形界面,而有人玩tic脚趾(视频)。一个问题是如何确定X还是O?我试着使用轮廓区域,但有时它不是一条封闭的线,所以它提供了一些小的,作为最大的轮廓面积。我尝试过的另一个想法是使用层次结构,如果它有3以上,它就是O,但是它会产生一些不好的结果。我不能用腐蚀,因为它也吃我的东西。我的代码:

代码语言:javascript
复制
struct myclass {
    bool operator() (Vec4i l1, Vec4i l2) { return (l1[0] < l2[0]); }
} myobjectv;

struct myclass1 {
    bool operator() (Vec4i l1, Vec4i l2) { return (l1[1] < l2[1]); }
} myobjecth;


using Contour = std::vector<cv::Point>;


void filtriranje(vector<Vec4i> lines, vector<Vec4i> &v_lines, vector<Vec4i> &h_lines){
for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i l = lines[i];
        double Angle = atan2(l[3] - l[1], l[2] - l[0]) * 180.0 / CV_PI;

        //vertikalne
        if ((abs(Angle) > 85) && (abs(Angle) <=92)){
            v_lines.push_back(lines[i]);

    }
    //horizontalne
    else if ((abs(Angle) >= 0) && (abs(Angle) <= 2)){
        h_lines.push_back(lines[i]);

    }

}



void uklanjanje_duplikata(vector<Vec4i> v_lines, vector<Vec4i> h_lines, vector<Vec4i> &vv_lines, vector<Vec4i> &hh_lines,Mat &cdst){
    int broj[10] = { 0 };
    if (v_lines.size() == 1){ vv_lines.push_back(v_lines[0]); line(cdst, Point(vv_lines[0][0], vv_lines[0][1]), Point(vv_lines[0][2], vv_lines[0][3]), Scalar(0, 255, 0), 3, CV_AA); }
    if (h_lines.size() == 1){ hh_lines.push_back(h_lines[0]); line(cdst, Point(hh_lines[0][0], hh_lines[0][1]), Point(hh_lines[0][2], hh_lines[0][3]), Scalar(0, 255, 0), 3, CV_AA); }
    sort(v_lines.begin(), v_lines.end(), myobjectv);
    if (v_lines.size() > 1){
        for (size_t i = 0; i < v_lines.size() - 1; i++)
        {
            for (size_t j = i + 1; j < v_lines.size(); j++)
            {
                Vec4i l1 = v_lines[i];
                Vec4i l2 = v_lines[j];
                if ((abs(l1[2] - l2[2]) < 47)){
                    if ((broj[i] == 0) && (broj[j] == 0))
                    {
                        Vec4i lnew;
                        lnew[0] =( l1[0] + l2[0])/2;
                        lnew[1] = (l1[1] + l2[1]) / 2;
                        lnew[2] = (l1[2] + l2[2]) / 2;
                        lnew[3] = (l1[3] + l2[3]) / 2;
                        vv_lines.push_back(lnew);
                        broj[i] = broj[i] + 1;
                        broj[j] = broj[j] + 1;
                    }

                }
                else{
                    if ((broj[i] == 0)){ vv_lines.push_back(l1); broj[i] = broj[i] + 1; }
                    if ((broj[j] == 0)){ vv_lines.push_back(l2); broj[j] = broj[j] + 1; }

                }
            }
        }
        for (size_t i = 0; i < vv_lines.size(); i++)
        {
            Vec4i lcr = vv_lines[i];
            line(cdst, Point(lcr[0], lcr[1]), Point(lcr[2], lcr[3]), Scalar(0, 255, 0), 3, CV_AA);
        }
    }
    int brojb[10] = { 0 };
    sort(h_lines.begin(), h_lines.end(), myobjecth);
    if (h_lines.size()>1){
        for (size_t i = 0; i < h_lines.size(); i++)
        {
            for (size_t j = i+1; j < h_lines.size() - 1; j++)
            {
                Vec4i l1 = h_lines[i];
                Vec4i l2 = h_lines[j];
                if ((abs(l1[1] - l2[1]) < 47)){
                    if ((brojb[i] == 0) && (brojb[j] == 0))
                    {
                        Vec4i lhnew;

                        hh_lines.push_back(l1);
                        brojb[i] = brojb[i]+1;
                        brojb[j] = brojb[j] + 1;
                    }

                }
                else{
                    if ((brojb[i] == 0)){ hh_lines.push_back(l1); brojb[i] = brojb[i] + 1; }
                    if ((brojb[j] == 0)){ hh_lines.push_back(l2); brojb[j] = brojb[j] + 1; }

                }
            }
        }
        for (size_t i = 0; i < hh_lines.size(); i++)
        {
            Vec4i lcr = hh_lines[i];
            line(cdst, Point(lcr[0], lcr[1]), Point(lcr[2], lcr[3]), Scalar(0, 255, 0), 3, CV_AA);
        }
    }


  }

void presek(vector<Vec4i> vv_lines, vector<Vec4i> hh_lines, vector<Point> &grid){
    Point P;
    int s = 0;
    for (size_t i = 0; i < hh_lines.size(); i++)
    {
        for (size_t j = 0; j < vv_lines.size(); j++)
        {
            Vec4i lb1 = hh_lines[i];
            Vec4i lb2 = vv_lines[j];
            float p1startx = lb1[0];
            float p1starty = lb1[1];
            float p1endx = lb1[2];
            float p1endy = lb1[3];
            float p2startx = lb2[0];
            float p2starty = lb2[1];
            float p2endx = lb2[2];
            float p2endy = lb2[3];

            if ((p2startx>=p1startx)&(p2startx <= p1endx)){
                P.x = p2startx;
                P.y = p1starty;
                grid.push_back(P);
                s++;

            }
        }
    }
}
void find_cross(vector<Vec4i> hh_lines, vector<Vec4i> vv_lines, vector<Point> grid, Point &cross1, Point &cross2, Point &cross3, Point &cross4){

    if ((hh_lines.size() == 2)&(vv_lines.size() == 2)){//kompletna mreza
        cross1 = grid[0];
        cross2 = grid[1];
        cross3 = grid[2];
        cross4 = grid[3];
        Vec4i lin = vv_lines[0];
        Vec4i linh = hh_lines[0];
        Vec4i linh2 = hh_lines[1];
        Vec4i linv2 = vv_lines[1];
        int g = linh[0];
        int s1 = lin[1];
        int p = cross1.x;
        int h = cross2.x;
        int cell_size = abs(p - h);

        //circle(cdst, cross1, 8, Scalar(0, 0, 255), 1, 8, 0);
        //circle(cdst, Point((cross4.x - cell_size), (cross4.y)), 8, Scalar(0, 0, 255), 1, 8, 0);
    }
    else if ((hh_lines.size() == 2)&(vv_lines.size() == 1)){//dve horizontalne i jedna vertikalna
        Vec4i lin = vv_lines[0];
        Vec4i linh = hh_lines[0];
        Vec4i linh2 = hh_lines[1];
        int flag[5] = { 0 };
        int p = linh[1];
        int h = linh2[1];
        int cell_size = abs(p - h);
        Point presek = grid[0];
        if (abs(presek.x - linh[0]) < abs(presek.x - linh[2])){ cross1 = grid[0]; flag[1] = 1; cross3 = grid[1]; flag[3] = 1; cross2.x = cross1.x + cell_size; cross2.y = cross1.y; cross4.x = cross2.x; cross4.y = cross3.y; }
        else { cross2 = grid[0]; flag[2] = 1; cross4 = grid[1]; flag[4] = 1; cross1.x = cross2.x - cell_size; cross1.y = cross2.y; cross3.x = cross4.x - cell_size; cross3.y = cross4.y; }


    }

    else if ((hh_lines.size() == 1)&(vv_lines.size() == 2)){//horizontalna i dve vertikalne
        Vec4i linv = vv_lines[0];
        Vec4i linv2 = vv_lines[1];
        Vec4i linh = hh_lines[0];
        int flag[5] = { 0 };
        int cell_size = abs(linv[0] - linv2[0]);
        Point presek = grid[0];
        int pocetak = linv[1];
        int kraj = linv[3];
        if (linv[3] > linv[1]){
            if (abs(presek.y - linv[3]) > abs(presek.y - linv[1])){ cross1 = grid[0]; flag[1] = 1; flag[2] = 1; cross2 = grid[1]; cross3.x = cross1.x; cross3.y = cross1.y + cell_size; cross4.x = cross2.x; cross4.y = cross2.y + cell_size; }
            else{ cross3 = grid[0]; flag[3] = 1; flag[4] = 1; cross4 = grid[1]; cross1.x = cross3.x; cross1.y = cross3.y - cell_size; cross2.x = cross4.x; cross2.y = cross4.y - cell_size; }
        }
        else{
            if (abs(presek.y - linv[3]) < abs(presek.y - linv[1])){ cross1 = grid[0]; flag[1] = 1; flag[2] = 1; cross2 = grid[1]; cross3.x = cross1.x; cross3.y = cross1.y + cell_size; cross4.x = cross2.x; cross4.y = cross2.y + cell_size; }
            else{ cross3 = grid[0]; flag[3] = 1; flag[4] = 1; cross4 = grid[1]; cross1.x = cross3.x; cross1.y = cross3.y - cell_size; cross2.x = cross4.x; cross2.y = cross4.y - cell_size; }
        }

        }
    else if ((hh_lines.size() == 1)&(vv_lines.size() == 1)){//jedna vertikalna jedna horizontalna

        Vec4i linv = vv_lines[0];
        Vec4i linh = hh_lines[0];
        Point presek = grid[0];
        int flag[5] = { 0 };


        int cell_size = 47;
        if (abs(linh[0] - presek.x) < abs(linh[2] - presek.x)){//leva linija vertikalna
            if (abs(linv[3] - presek.y) < abs(linv[1] - presek.y)){ cross1 = grid[0]; cross3.x = cross1.x; cross3.y = cross1.y + cell_size; cross2.x = cross1.x + cell_size; cross2.y = cross1.y; cross4.x = cross3.x + cell_size; cross4.y = cross3.y; }//gornja horizontala
            else { cross3 = presek; cross1.x = cross3.x; cross1.y = cross3.y - cell_size; cross2.x = cross1.x + cell_size; cross2.y = cross1.y; cross4.x = cross3.x + cell_size; cross4.y = cross3.y; }
        }

        else {//desna vertikalna
            int cell_size = 47;
            if (linv[1] > linv[3]){
                if (abs(linv[3] - presek.y) < abs(linv[1] - presek.y))
                {
                    cross2 = grid[0]; cross1.x = cross2.x - cell_size; cross1.y = cross2.y; cross3.x = cross1.x; cross3.y = cross1.y + cell_size; cross4.x = cross3.x + cell_size; cross4.y = cross3.y;
                }
                else{ cross4 = grid[0]; cross3.x = cross4.x - cell_size; cross3.y = cross4.y; cross2.x = cross4.x; cross2.y = cross4.y - cell_size; cross1.x = cross2.x - cell_size; cross1.y = cross2.y; }
            }
            else{
                if (abs(linv[3] - presek.y) > abs(linv[1] - presek.y))
                {
                    cross2 = grid[0]; cross1.x = cross2.x - cell_size; cross1.y = cross2.y; cross3.x = cross1.x; cross3.y = cross1.y + cell_size; cross4.x = cross3.x + cell_size; cross4.y = cross3.y;
                }
                else{ cross4 = grid[0]; cross3.x = cross4.x - cell_size; cross3.y = cross4.y; cross2.x = cross4.x; cross2.y = cross4.y - cell_size; cross1.x = cross2.x - cell_size; cross1.y = cross2.y; }


            }
        }
    }
}

void set_ROI(Point cross1, Point cross2, Point cross3, Point cross4, Mat dst, Mat cdst, int cell_size,Mat &roi1, Mat &roi2, Mat &roi3, Mat &roi4, Mat &roi5, Mat &roi6, Mat &roi7, Mat &roi8, Mat &roi9){

    roi1 = dst(Rect((cross1.x - cell_size), (cross1.y - cell_size), cell_size, cell_size));
    rectangle(cdst, Point((cross1.x - cell_size), (cross1.y - cell_size)), cross1, Scalar(0, 0, 255), 3, CV_AA);
    roi4 = dst(Rect((cross1.x - cell_size), cross1.y, cell_size, cell_size));
    rectangle(cdst, Point((cross1.x - cell_size), cross1.y), cross3, Scalar(0, 0, 255), 3, CV_AA);
    roi7 = dst(Rect((cross3.x - cell_size), cross3.y, cell_size, cell_size));
    rectangle(cdst, Point((cross3.x - cell_size), cross3.y), Point(cross3.x, cross3.y + cell_size), Scalar(0, 0, 255), 3, CV_AA);
    roi2 = dst(Rect(cross1.x, (cross1.y - cell_size), cell_size, cell_size));
    rectangle(cdst, Point(cross1.x, (cross1.y - cell_size)), cross2, Scalar(0, 0, 255), 3, CV_AA);
    roi5 = dst(Rect(cross1.x, cross1.y, cell_size, cell_size));
    rectangle(cdst, Point(cross1.x, cross1.y), cross4, Scalar(0, 0, 255), 3, CV_AA);
    roi8 = dst(Rect(cross3.x, cross3.y, cell_size, cell_size));
    rectangle(cdst, cross3, Point(cross4.x, cross4.y + cell_size), Scalar(0, 0, 255), 3, CV_AA);
    roi3 = dst(Rect(cross2.x, (cross2.y - cell_size), cell_size, cell_size));
    rectangle(cdst, Point(cross2.x, (cross2.y - cell_size)), Point(cross2.x + cell_size, cross2.y), Scalar(0, 0, 255), 3, CV_AA);
    roi6 = dst(Rect(cross2.x, cross2.y, cell_size, cell_size));
    rectangle(cdst, cross2, Point(cross4.x + cell_size, cross4.y), Scalar(0, 0, 255), 3, CV_AA);
    roi9 = dst(Rect(cross4.x, cross4.y, cell_size, cell_size));
    rectangle(cdst, cross4, Point(cross4.x + cell_size, cross4.y + cell_size), Scalar(0, 0, 255), 3, CV_AA);


}


int main(int argc, char** argv)
{

    //cvNamedWindow("Prvi Video");
    vector<Rect*> components(250, (Rect *)NULL);
    VideoCapture video1;
    int vektor, cell_size;

    int width, height, frames1, fps1;
    int popunjeno[9] = { 0 };
    int ukupno_komponenti[3][3] = { 0 };
    video1.open(argv[1]);
    fps1 = video1.get(CV_CAP_PROP_FPS);
    width = video1.get(CAP_PROP_FRAME_WIDTH);
    height = video1.get(CAP_PROP_FRAME_HEIGHT);
    frames1 = video1.get(CAP_PROP_FRAME_COUNT);

    vector<Point> preseci;
    vector<Vec4i> vertikale;
    vector<Vec4i> horizontale;

    cout << "Video1 " << argv[1] <<
        ": width=" << width <<
        ", height=" << height <<
        ", frames=" << frames1 <<
        ", fps1=" << fps1 << endl;


    int i = 0;
    int j = 0;




    Mat src, tmp, dst, cdst, krug;
    Mat frameTime1(height, width, CV_8UC3, Scalar(0, 0, 0));
    int fvd = 0;
    int r;
    while (1)
    {
        fvd++;

        cout << fvd;
        video1 >> src;
        bool bSuccess = video1.read(src);
        if (!bSuccess) //if not success, break loop
        {
            cout << "ERROR: Cannot read a frame from video file" << endl;
            break;
        }
        Mat roi_w1;
        roi_w1 = src(Rect(150, 50, 320, 320));
        GaussianBlur(roi_w1, roi_w1, Size(11, 11), 0);
        Canny(roi_w1, dst, 50, 200, 3);
        cvtColor(dst, cdst, CV_GRAY2BGR);
        double povrsina = 0;
        vector<Vec4i> lines;
        vector<Vec4i> h_lines;
        vector<Vec4i> v_lines;
        vector<Vec4i> hh_lines;
        vector<Vec4i> vv_lines;
        vector<Mat> ROI;
        Point cross1, cross2, cross3, cross4;

        Mat roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9;
        vector<Point> grid;
        if (fvd == 1){//prvi frejm
            HoughLinesP(dst, lines, 1, CV_PI / 220, 50, 150, 50);
            filtriranje(lines, v_lines, h_lines);
            uklanjanje_duplikata(v_lines, h_lines, vv_lines, hh_lines, cdst);
            if ((hh_lines.size() == 2)&(vv_lines.size() == 2)){

                presek(vv_lines, hh_lines, grid);//u grid su tacke preseka
                cell_size = abs(grid[0].x - grid[1].x);
                find_cross(hh_lines, vv_lines, grid, cross1, cross2, cross3, cross4);//potpuna rekonstrukcija mreze,resen problem ako nisu nadjene sve cetiri linije
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
                vertikale = vv_lines;
                horizontale = hh_lines;
                preseci.push_back(cross1);
                preseci.push_back(cross2);
                preseci.push_back(cross3);
                preseci.push_back(cross4);

            }
            else if ((hh_lines.size() == 1) & (vv_lines.size() == 2)) {
                presek(vv_lines, hh_lines, grid);//u grid su tacke preseka
                find_cross(hh_lines, vv_lines, grid, cross1, cross2, cross3, cross4);
                vertikale = vv_lines;
                horizontale = hh_lines;
                preseci.push_back(cross1);
                preseci.push_back(cross2);
                preseci.push_back(cross3);
                preseci.push_back(cross4);
                cell_size = abs(vv_lines[0][0] - vv_lines[1][0]);//potpuna rekonstrukcija mreze,resen problem ako nisu nadjene sve cetiri linije
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);

            }
            else if ((hh_lines.size() == 2)& (vv_lines.size() == 1)){
                presek(vv_lines, hh_lines, grid);//u grid su tacke preseka
                find_cross(hh_lines, vv_lines, grid, cross1, cross2, cross3, cross4);
                cell_size = abs(hh_lines[0][1] - hh_lines[1][1]);//potpuna rekonstrukcija mreze,resen problem ako nisu nadjene sve cetiri linije
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
                vertikale = vv_lines;
                horizontale = hh_lines;
                preseci.push_back(cross1);
                preseci.push_back(cross2);
                preseci.push_back(cross3);
                preseci.push_back(cross4);

            }

            ROI.push_back(roi1);
            ROI.push_back(roi2);
            ROI.push_back(roi3);
            ROI.push_back(roi4);
            ROI.push_back(roi5);
            ROI.push_back(roi6);
            ROI.push_back(roi7);
            ROI.push_back(roi8);
            ROI.push_back(roi9);

        }
        vector<Rect*> components(250, (Rect *)NULL);
        Mat motion, motion2[3], f1, f2, f3, fout1, maska;
        absdiff(frameTime1, src, motion);
        split(motion, motion2);
        threshold(motion2[0], f1, 20, 255, CV_THRESH_BINARY);
        threshold(motion2[1], f2, 20, 255, CV_THRESH_BINARY);
        threshold(motion2[2], f3, 20, 255, CV_THRESH_BINARY);
        bitwise_or(f1, f2, fout1);
        bitwise_or(fout1, f3, maska);
        //morphologyEx(maska, maska, MORPH_OPEN, Mat());
        dilate(maska, maska, Mat());
        dilate(maska, maska, Mat());
        dilate(maska, maska, Mat());
        dilate(maska, maska, Mat());
        dilate(maska, maska, Mat());
        dilate(maska, maska, Mat());

        int c = countNonZero(maska);
        src.copyTo(frameTime1);
        //if (fvd == 138){
        if (c < 2000){//ruka nije u kadru
            vector<Vec4i>().swap(lines);
            vector<Vec4i>().swap(h_lines);
            vector<Vec4i>().swap(hh_lines);
            vector<Vec4i>().swap(v_lines);
            vector<Vec4i>().swap(vv_lines);
            vector<Mat>().swap(ROI);
            HoughLinesP(dst, lines, 1, CV_PI / 200, 50, 150, 30);
            filtriranje(lines, v_lines, h_lines);
            uklanjanje_duplikata(v_lines, h_lines, vv_lines, hh_lines, cdst);
            Mat roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9;
            vector<Point> grid;

            if ((hh_lines.size() == 0)&(vv_lines.size() == 2)){
                Vec4i ver1 = vv_lines[0];
                Vec4i ver2 = vv_lines[1];
                cell_size = 48;
                if (ver1[1] > ver1[3]){
                    cross1.x = ver1[2];
                    cross1.y = ver1[3] + cell_size;
                    cross2.x = ver2[2];
                    cross2.y = cross1.y;
                    cross3.x = cross1.x;
                    cross3.y = cross1.y + cell_size;
                    cross4.x = cross2.x;
                    cross4.y = cross1.y + cell_size;
                }
                else{
                    cross1.x = ver1[0];
                    cross1.y = ver1[1] + cell_size;
                    cross2.x = ver2[0];
                    cross2.y = cross1.y;
                    cross3.x = cross1.x;
                    cross3.y = cross1.y + cell_size;
                    cross4.x = cross2.x;
                    cross4.y = cross1.y + cell_size;

                }

                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
            }
            else if ((vv_lines.size() == 0)&(hh_lines.size() == 2)){
                Vec4i h1 = hh_lines[0];
                Vec4i h2 = hh_lines[1];
                cross1.x = h1[0] + cell_size;
                cross1.y = h1[1];
                cross2.x = h1[0] + 2 * cell_size;
                cross2.y = h1[1];
                cross3.x = h1[0] + cell_size;
                cross3.y = h2[1];
                cross4.x = h2[0] + 2 * cell_size;
                cross4.y = h2[1];
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
            }
            else if ((hh_lines.size() == 2)&(vv_lines.size() == 2)){
                presek(vv_lines, hh_lines, grid);//u grid su tacke preseka
                find_cross(hh_lines, vv_lines, grid, cross1, cross2, cross3, cross4);//potpuna rekonstrukcija mreze,resen problem ako nisu nadjene sve cetiri linije
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
            }
            else if ((hh_lines.size() == 1) & (vv_lines.size() == 2)) {
                presek(vv_lines, hh_lines, grid);//u grid su tacke preseka
                find_cross(hh_lines, vv_lines, grid, cross1, cross2, cross3, cross4);//potpuna rekonstrukcija mreze,resen problem ako nisu nadjene sve cetiri linije
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
            }
            else if ((hh_lines.size() == 2)& (vv_lines.size() == 1)){
                presek(vv_lines, hh_lines, grid);//u grid su tacke preseka
                find_cross(hh_lines, vv_lines, grid, cross1, cross2, cross3, cross4);//potpuna rekonstrukcija mreze,resen problem ako nisu nadjene sve cetiri linije
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
            }
            else if ((hh_lines.size() == 2)&(vv_lines.size() > 2)){
                presek(vertikale, hh_lines, grid);//u grid su tacke preseka
                find_cross(hh_lines, vertikale, grid, cross1, cross2, cross3, cross4);//potpuna rekonstrukcija mreze,resen problem ako nisu nadjene sve cetiri linije
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
            }
            else if ((hh_lines.size() > 2) &(vv_lines.size() == 2)){
                presek(vv_lines, horizontale, grid);//u grid su tacke preseka
                find_cross(horizontale, vv_lines, grid, cross1, cross2, cross3, cross4);//potpuna rekonstrukcija mreze,resen problem ako nisu nadjene sve cetiri linije
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
            }
            else if ((hh_lines.size() == 1)& (vv_lines.size() == 1)){
                presek(vv_lines, hh_lines, grid);//u grid su tacke preseka
                find_cross(hh_lines, vv_lines, grid, cross1, cross2, cross3, cross4);//potpuna rekonstrukcija mreze,resen problem ako nisu nadjene sve cetiri linije
                set_ROI(cross1, cross2, cross3, cross4, dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9);
            }
            else{ set_ROI(preseci[0], preseci[1], preseci[2], preseci[3], dst, cdst, cell_size, roi1, roi2, roi3, roi4, roi5, roi6, roi7, roi8, roi9); }



            roi1 = roi1 > 128;
            roi2 = roi2 > 128;
            roi3 = roi3 > 128;
            roi4 = roi4 > 128;
            roi5 = roi5 > 128;
            roi6 = roi6 > 128;
            roi7 = roi7 > 128;
            roi8 = roi8 > 128;
            roi9 = roi9 > 128;

            int m = 0;
            ROI.push_back(roi1);
            ROI.push_back(roi2);
            ROI.push_back(roi3);
            ROI.push_back(roi4);
            ROI.push_back(roi5);
            ROI.push_back(roi6);
            ROI.push_back(roi7);
            ROI.push_back(roi8);
            ROI.push_back(roi9);
            int ks;
            int simbol = 0;
            if (r == 1){
                for (size_t k = 0; k < 9; k++)
                {
                    if (popunjeno[k] == 0){
                        vector<Contour> contour_vec;
                        vector<Vec4i> hierarchy;
                        vector<Vec4i> lines_junk;
                        Mat tmp, tmp1;

                        //tmp = ROI[k](Rect(15, 10, 30, 30));
                        //dilate(tmp, tmp, Mat());
                        ROI[k].copyTo(tmp);
                        ROI[k].copyTo(tmp1);
                        HoughLinesP(tmp, lines_junk, 1, CV_PI / 220, 30, 15, 10);
                        for (size_t i = 0; i < lines_junk.size(); i++)
                        {
                            Vec4i l = lines_junk[i];
                            line(tmp1, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 0), 3, CV_AA);
                        }
                        int ukupno_komponenti;
                        tmp = tmp1(Rect(5, 5, 35, 35));
                        int largest_area = 0;
                        int largest_contour_index = 0;
                        findContours(tmp1, contour_vec, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
                        if ((hierarchy.size() == 3)){
                            popunjeno[k] = 1;

                        }

                        else if (((hierarchy.size() > 3))){
                            popunjeno[k] = -1;

                        }


                    }



                }
                r = -1;
                //imshow("detected lines", cdst);
                //waitKey();
            }


        }
    //}
        else{ r = 1;    continue; }




    }

    return 0;



}

这些是我的细胞:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-03 18:09:17

最好是计算其中一幅图像的底部投影,并以此确定它是X还是O:底部投影只是一个ints数组,其中索引I中的每个单元格都包含图像中从下到上到第一个非黑色像素的像素数。

对于X图像,你将得到一个投影,它包含一个上升序列,然后一个降序,对于O图像,你将得到一个降序,然后是上升序列。

要计算投影,只需计算每列的像素数,直到达到非黑色像素为止,因为图像中的噪声,如果从单元格i中的值大于或小于2或更小,则需要从投影数组中省略一个值,还需要在投影数组的开始和结尾省略较高的值,因为该值可能是整列的总和(从下到上的总和)。

记住要从投影中删除所有的第一个和最后一个值--只留下一个比高度/2检查序列低的值:

代码语言:javascript
复制
    private bool IsDescending(int[] proj,int len)
    {
            for (int i = 0; i < len-1; i++)
            {
                if (proj[i] < proj[i + 1])
                    return false;
            }
            return true;
    }
    private bool IsAscending(int[] proj,int len)
    {
            for (int i = 0; i < len-1; i++)
            {
                if (proj[i] > proj[i + 1])
                    return false;
            }
            return true;
    }

祝好运。

票数 2
EN

Stack Overflow用户

发布于 2016-06-03 18:05:38

我过去通过比较检测到的轮廓和我已经看到的形状最接近的轮廓(最佳匹配)来做到这一点。

多么?有一个OpenCV函数为我们做这件事。它需要一对等高线,并返回一个度量,显示它们的相似之处(我认为双值0到1)。因此,如果您已经有X和O的两个图像,并且检测到了一个形状,那么您只需对已经拥有的每个图像调用该函数,它就会返回两个值。然后,您只需比较这两个值,看看它是O还是X(值越小,轮廓越相似)。

这里:检查3节。匹配形状 functions.html#gsc.tab=0

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37620662

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档