2

私はこの画像を持っています:

そして、画像から三角形と長方形を取り出したいです。以下のコードには、三角形用と長方形用の 2 つのアルゴリズムがあります。しかし、それらは非常に似ています。しかし、この方法では、三角形をより明るくすることしかできません。誰でも私を助けてください。

IplImage* DetectAndDrawTriang(IplImage* img){
    CvSeq* contours;
    CvSeq* result;
    CvMemStorage *storage = cvCreateMemStorage(0);
    int d=30;

    IplImage* ret = cvCreateImage(cvGetSize(img), 8, 3);
    IplImage* temp = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
    cvSet(ret,cvScalar(0,0,0));
    cvCvtColor(img, temp, CV_BGR2GRAY);
    cvThreshold( temp, temp, 180, 255, CV_THRESH_BINARY );
    //cvSmooth(temp, temp, CV_GAUSSIAN, 9, 9, 0,0);
    cvNamedWindow("thre");
    cvShowImage("thre", temp);

    cvFindContours(temp, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

    while(contours)
    {
        result = cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.1, 0);
        if(result->total==3)
        {
            CvPoint *pt[3];
            for(int i=0;i<3;i++)
                pt[i] = (CvPoint*)cvGetSeqElem(result, i);


            if((int)sqrt((pt[0]->x-pt[2]->x)*(pt[0]->x-pt[2]->x)+(pt[0]->y-pt[2]->y)*(pt[0]->y-pt[2]->y))>=d && (int)sqrt((pt[0]->x-pt[1]->x)*(pt[0]->x-pt[1]->x)+(pt[0]->y-pt[1]->y)*(pt[0]->y-pt[1]->y))>=d && (int)sqrt((pt[1]->x-pt[2]->x)*(pt[1]->x-pt[2]->x)+(pt[1]->y-pt[2]->y)*(pt[1]->y-pt[2]->y))>=d)
            {
                cvLine(ret, *pt[0], *pt[1], cvScalar(255,255,255));

                cvLine(ret, *pt[1], *pt[2], cvScalar(255,255,255));

                cvLine(ret, *pt[2], *pt[0], cvScalar(255,255,255));
            }
        }
        contours = contours->h_next;
    }

    cvReleaseImage(&temp);
    cvReleaseMemStorage(&storage);

    return ret;

}
4

2 に答える 2

2

私が考えることができる 1 つのアイデアは、cv::matchShapes 関数を使用することです (Ipl 画像の代わりに Mat で cv2 ライブラリを使用することをお勧めします)。matchShapes は、検出したいオブジェクトの Mat と、比較したいオブジェクトの Mat を取ります。したがって、あなたの場合、三角形と正方形の輪郭のマットを作成し、それらの画像を検索している画像の各輪郭と比較できます。

オブジェクトは静的であるため、単純にテンプレート マッチングを行うことを検討することもできます。cv::matchTemplate と、上記の段落とほぼ同じ考え方を確認してください。

于 2012-11-30T17:47:00.737 に答える
0

輪郭が完全であることを確認できる場合は、近似ポリが適したソリューションです。等高線が正方形であるが閉じていない場合は、近似後、4つのセグメントと3つのコーナーを持つ線になります。

別の解決策は、等高線ポイントの周りにボックスを合わせ(これを行う機能があります)、幅/高さの比率を確認することです。次に、等高線リストの個々の線分をテストして、ボックスの側面と一致するかどうかを確認できます。

于 2012-11-30T20:16:08.750 に答える