久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

正方形檢測(cè)沒(méi)有找到正方形

Square detection doesn#39;t find squares(正方形檢測(cè)沒(méi)有找到正方形)
本文介紹了正方形檢測(cè)沒(méi)有找到正方形的處理方法,對(duì)大家解決問(wèn)題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧!

問(wèn)題描述

我正在使用 OpenCV 庫(kù)示例中提供的程序 squares.c.它適用于每個(gè)圖像,但我真的不明白為什么它不能識(shí)別該圖像中繪制的正方形

DILATE 之后:

RESULT 圖像(紅色)http://img267.imageshack.us/img267/8016/resultuq.jpg

如您所見(jiàn),未檢測(cè)到正方形.

檢測(cè)后我需要提取正方形中包含的區(qū)域......沒(méi)有ROI怎么可能?

解決方案

下面的源代碼展示了 Square Detector 程序的一個(gè)小變化.它并不完美,但它說(shuō)明了解決您的問(wèn)題的一種方法.

您可以此代碼與原始代碼進(jìn)行比較并檢查所做的所有更改,但主要的更改是:

  • 將閾值級(jí)別的數(shù)量減少到 2.

  • findSquares()的開(kāi)頭,擴(kuò)大圖像檢測(cè)細(xì)小的白色方塊,然后模糊整個(gè)圖像,因此算法不會(huì)將大海和天空檢測(cè)為單個(gè)方塊.

編譯后,使用以下語(yǔ)法運(yùn)行應(yīng)用程序:./app

//平方檢測(cè)器"程序.//它順序加載多個(gè)圖像并嘗試在其中找到正方形//每張圖片#include "highgui.h"#include "cv.h"#include #include <math.h>#include 使用命名空間 cv;使用命名空間標(biāo)準(zhǔn);無(wú)效的幫助(){cout<<"
一個(gè)使用金字塔縮放、Canny、輪廓、輪廓簡(jiǎn)化和
的程序"內(nèi)存存儲(chǔ)(所有人都可以找到)
""圖像列表中的方塊 pic1-6.png
""返回在圖像上檢測(cè)到的正方形序列.
""序列存儲(chǔ)在指定的內(nèi)存中
"呼叫:
""./平方
""使用 OpenCV 版本 %s
" <<CV_VERSION <<"
" <<結(jié)束;}整數(shù)閾值 = 50,N = 2;//karlphillip:將 N 減少到 2,是 11.const char* wndname = "平方檢測(cè)演示";//輔助函數(shù)://找到向量之間夾角的余弦值//從 pt0->pt1 和從 pt0->pt2雙角(點(diǎn)pt1,點(diǎn)pt2,點(diǎn)pt0){雙 dx1 = pt1.x - pt0.x;雙 dy1 = pt1.y - pt0.y;雙 dx2 = pt2.x - pt0.x;雙 dy2 = pt2.y - pt0.y;返回 (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);}//返回在圖像上檢測(cè)到的正方形序列.//序列存儲(chǔ)在指定的內(nèi)存中void findSquares( const Mat& image, vector<vector<Point> >& squares ){squares.clear();Mat pyr, timg, gray0(image.size(), CV_8U), gray;//karlphillip: 擴(kuò)大圖像,以便此技術(shù)可以檢測(cè)白色方塊,墊出(圖像);擴(kuò)張(出,出,墊(),點(diǎn)(-1,-1));//然后模糊它,使海洋/大海成為一大段,以避免將它們檢測(cè)為 2 個(gè)大方塊.中值模糊(出,出,7);//縮小和放大圖像以濾除噪聲pyrDown(out, pyr, Size(out.cols/2, out.rows/2));pyrUp(pyr, timg, out.size());矢量<矢量<點(diǎn)>>輪廓;//在圖像的每個(gè)顏色平面中找到正方形for( int c = 0; c <3; c++ ){int ch[] = {c, 0};mixChannels(&timg, 1, &gray0, 1, ch, 1);//嘗試幾個(gè)閾值級(jí)別for( int l = 0; l = (l+1)*255/N;}//找到輪廓并將它們?nèi)看鎯?chǔ)為列表findContours(灰色,輪廓,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);矢量<點(diǎn)>約;//測(cè)試每個(gè)輪廓for( size_t i = 0; i 1000 & &isContourConvex(Mat(approx)) ){雙最大余弦 = 0;for( int j = 2; j <5; j++ ){//找到關(guān)節(jié)邊緣之間夾角的最大余弦值雙余弦 = fabs(angle(approx[j%4],approx[j-2],approx[j-1]));maxCosine = MAX(maxCosine, cosine);}//如果所有角度的余弦都很小//(所有角度都是~90度)然后寫(xiě)quandrange//頂點(diǎn)到結(jié)果序列如果(最大余弦<0.3)squares.push_back(大約);}}}}}//該函數(shù)繪制圖像中的所有方塊void drawSquares( Mat& image, const vector<vector<Point> >& squares ){for( size_t i = 0; i < squares.size(); i++ ){const Point* p = &squares[i][0];int n = (int)squares[i].size();polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, CV_AA);}imshow(wndname,圖像);}int main(int argc, char** argv){如果 (argc <2){cout<<用法:./program <文件>"<<結(jié)束;返回-1;}//static const char* names[] = { "pic1.png", "pic2.png", "pic3.png",//"pic4.png", "pic5.png", "pic6.png", 0 };靜態(tài)常量字符*名稱(chēng)[] = { argv[1], 0 };幫助();命名窗口( wndname, 1 );矢量<矢量<點(diǎn)>>正方形;for( int i = 0; names[i] != 0; i++ ){Mat image = imread(names[i], 1);如果(圖像.空()){cout<<無(wú)法加載" <<名稱(chēng)[i] <<結(jié)束;繼續(xù);}findSquares(圖像,正方形);drawSquares(圖像,正方形);imwrite("out.jpg", image);int c = waitKey();如果((字符)c == 27 )休息;}返回0;}

輸出:

I'm using the program squares.c available in the samples of OpenCV libraries. It works well with every image, but I really can't figure it out why it doesn't recognize the square drawn in that image

http://desmond.imageshack.us/Himg12/scaled.php?server=12&filename=26725680.jpg&res=medium

After CANNY:

After DILATE:

The RESULT image (in red) http://img267.imageshack.us/img267/8016/resultuq.jpg

As you can see, the square is NOT detected.

After the detection I need to extract the area contained in the square...How is it possible without a ROI?

解決方案

The source code below presents a small variation of the Square Detector program. It's not perfect, but it illustrates one way to approach your problem.

You can diff this code to the original and check all the changes that were made, but the main ones are:

  • Decrease the number of threshold levels to 2.

  • In the beginning of findSquares(), dilate the image to detect the thin white square, and then blur the entire image so the algorithm doesn't detect the sea and the sky as individual squares.

Once compiled, run the application with the following syntax: ./app <image>

// The "Square Detector" program.
// It loads several images sequentially and tries to find squares in
// each image

#include "highgui.h"
#include "cv.h"

#include <iostream>
#include <math.h>
#include <string.h>

using namespace cv;
using namespace std;

void help()
{
        cout <<
        "
A program using pyramid scaling, Canny, contours, contour simpification and
"
        "memory storage (it's got it all folks) to find
"
        "squares in a list of images pic1-6.png
"
        "Returns sequence of squares detected on the image.
"
        "the sequence is stored in the specified memory storage
"
        "Call:
"
        "./squares
"
    "Using OpenCV version %s
" << CV_VERSION << "
" << endl;
}


int thresh = 50, N = 2; // karlphillip: decreased N to 2, was 11.
const char* wndname = "Square Detection Demo";

// helper function:
// finds a cosine of angle between vectors
// from pt0->pt1 and from pt0->pt2
double angle( 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;
    return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}

// returns sequence of squares detected on the image.
// the sequence is stored in the specified memory storage
void findSquares( const Mat& image, vector<vector<Point> >& squares )
{
    squares.clear();

    Mat pyr, timg, gray0(image.size(), CV_8U), gray;

    // karlphillip: dilate the image so this technique can detect the white square,
    Mat out(image);
    dilate(out, out, Mat(), Point(-1,-1));
    // then blur it so that the ocean/sea become one big segment to avoid detecting them as 2 big squares.
    medianBlur(out, out, 7);

    // down-scale and upscale the image to filter out the noise
    pyrDown(out, pyr, Size(out.cols/2, out.rows/2));
    pyrUp(pyr, timg, out.size());
    vector<vector<Point> > contours;

    // find squares in every color plane of the image
    for( int c = 0; c < 3; c++ )
    {
        int ch[] = {c, 0};
        mixChannels(&timg, 1, &gray0, 1, ch, 1);

        // 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)
                Canny(gray0, gray, 0, thresh, 5);
                // dilate canny output to remove potential
                // holes between edge segments
                dilate(gray, gray, Mat(), Point(-1,-1));
            }
            else
            {
                // apply threshold if l!=0:
                //     tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
                gray = gray0 >= (l+1)*255/N;
            }

            // find contours and store them all as a list
            findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

            vector<Point> approx;

            // test each contour
            for( size_t i = 0; i < contours.size(); i++ )
            {
                // approximate contour with accuracy proportional
                // to the contour perimeter
                approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);

                // square contours should have 4 vertices after approximation
                // relatively large area (to filter out noisy contours)
                // and be convex.
                // Note: absolute value of an area is used because
                // area may be positive or negative - in accordance with the
                // contour orientation
                if( approx.size() == 4 &&
                    fabs(contourArea(Mat(approx))) > 1000 &&
                    isContourConvex(Mat(approx)) )
                {
                    double maxCosine = 0;

                    for( int j = 2; j < 5; j++ )
                    {
                        // find the maximum cosine of the angle between joint edges
                        double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                        maxCosine = MAX(maxCosine, cosine);
                    }

                    // if cosines of all angles are small
                    // (all angles are ~90 degree) then write quandrange
                    // vertices to resultant sequence
                    if( maxCosine < 0.3 )
                        squares.push_back(approx);
                }
            }
        }
    }
}


// the function draws all the squares in the image
void drawSquares( Mat& image, const vector<vector<Point> >& squares )
{
    for( size_t i = 0; i < squares.size(); i++ )
    {
        const Point* p = &squares[i][0];
        int n = (int)squares[i].size();
        polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, CV_AA);
    }

    imshow(wndname, image);
}


int main(int argc, char** argv)
{
    if (argc < 2)
    {
        cout << "Usage: ./program <file>" << endl;
        return -1;
    }

//    static const char* names[] = { "pic1.png", "pic2.png", "pic3.png",
//        "pic4.png", "pic5.png", "pic6.png", 0 };
    static const char* names[] = { argv[1], 0 };

    help();
    namedWindow( wndname, 1 );
    vector<vector<Point> > squares;

    for( int i = 0; names[i] != 0; i++ )
    {
        Mat image = imread(names[i], 1);
        if( image.empty() )
        {
            cout << "Couldn't load " << names[i] << endl;
            continue;
        }

        findSquares(image, squares);
        drawSquares(image, squares);
        imwrite("out.jpg", image);

        int c = waitKey();
        if( (char)c == 27 )
            break;
    }

    return 0;
}

Outputs:

這篇關(guān)于正方形檢測(cè)沒(méi)有找到正方形的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來(lái)源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問(wèn)題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

Assertion failed (size.widthgt;0 amp;amp; size.heightgt;0)(斷言失敗(size.width0 amp;amp; size.height0))
Rotate an image in C++ without using OpenCV functions(在 C++ 中旋轉(zhuǎn)圖像而不使用 OpenCV 函數(shù))
OpenCV: process every frame(OpenCV:處理每一幀)
Why can#39;t I open avi video in openCV?(為什么我不能在 openCV 中打開(kāi) avi 視頻?)
OpenCV unable to set up SVM Parameters(OpenCV 無(wú)法設(shè)置 SVM 參數(shù))
Convert a single color with cvtColor(使用 cvtColor 轉(zhuǎn)換單一顏色)
主站蜘蛛池模板: 亚洲国产午夜 | 日韩中字幕 | 日本久久网 | 欧美1区2区| 999在线精品 | 精品91久久 | 久久一级 | 日韩欧美国产一区二区 | 精品日韩在线 | 日韩成人中文字幕 | 欧美一级淫片免费视频黄 | 天堂视频一区 | 国产精品www | 成人av免费 | 日韩成人在线观看 | 91精品一区 | 日韩精品成人一区二区三区视频 | 国产精品久久久久aaaa九色 | 国产激情91久久精品导航 | 国内91在线 | 超碰电影 | 亚洲精品一二三 | 亚洲女人天堂网 | 中文字幕在线免费观看 | 青青草华人在线视频 | 精品一区二区三区视频在线观看 | 在线观看免费观看在线91 | 欧美xxxx在线| 亚洲啪啪一区 | 一区二区久久 | jvid精品资源在线观看 | 国产欧美日韩一区二区三区在线 | 久久精品—区二区三区 | 久久免费资源 | 国产一区不卡 | av在线播放免费 | 国产精品久久久久久av公交车 | 日本视频一区二区三区 | 国产精品日韩欧美一区二区三区 | 中文字幕日韩在线 | 国产成人jvid在线播放 |