0

以下のような画像があります。

点字

このソース コードを使用して、画像内の各ドットの中心座標を抽出することに成功しました。

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cv.h>
#include <iostream>
#include <vector>

int main(int argc, char **argv)
{
    cv::Mat matSrc,matTmp,matDst;
    cv::Mat matV,matROI;
    std::vector<cv::Mat> vectorHSV;
    std::vector<std::vector<cv::Point> > contours;
    std::vector<cv::Vec4i> hierarchy;
    matSrc = cv::imread(argv[1],1);
//    matSrc = cv::imread("123.jpg",1);
//    cv::imshow("Source", matSrc);
    cv::cvtColor(matSrc,matTmp,CV_RGB2HSV);
    cv::split(matTmp,vectorHSV);
    matV = vectorHSV[2];
    matV.copyTo(matTmp);
    cv::normalize(matTmp,matTmp,0,255,CV_MINMAX,CV_8UC1);
    cv::medianBlur(matTmp,matTmp,5);
    cv::adaptiveThreshold(matTmp,matTmp,255,CV_ADAPTIVE_THRESH_GAUSSIAN_C,CV_THRESH_BINARY_INV,125,7);
    cv::equalizeHist(matTmp,matTmp);
//    cv::erode(matTmp,matTmp,cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3,3)));
    cv::morphologyEx(matTmp,matTmp,cv::MORPH_CLOSE,cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3,3)));
    cv::Canny(matTmp,matTmp,50,150,3);
    cv::Rect ROI(0,0,matTmp.cols,matTmp.rows); 
    matROI = matTmp(ROI);
    cv::findContours(matROI,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_TC89_KCOS,cv::Point(0,0));
    std::vector<cv::Moments> muDots(contours.size());
    std::vector<cv::Point> mcDots(contours.size());
    for(size_t c=0;c < contours.size();c++)
    {
        muDots[c] = cv::moments(contours[c],false);
        mcDots[c] = cv::Point(static_cast<int>(muDots[c].m10/muDots[c].m00) , static_cast<int>(muDots[c].m01/muDots[c].m00));
    }
    for(int allDots=0;allDots < mcDots.size();allDots++)
    {
        std::cout << allDots << ": " << mcDots[allDots].x << "," << mcDots[allDots].y << std::endl;
    }

    matTmp.copyTo(matDst);
    imshow("ROI",matROI);
//    imshow("Result", matDst);
    cv::waitKey(0);
    return 0;
}

私が聞きたいのは、輪郭が存在するかどうかを処理する方法です。簡単に説明すると、このアルゴリズムで次のようにしたいと思います。

for(x=0;x < Image.cols;x++)
    {
        for(y=0;y < Image.rows;y++)
        {
            if(Contour coordinates at X,Y = Exist)
            {
                 vectorBraille.push_back = 1;
            }
            else
            {
                 vectorBraille.push_back = 0;
             } 
        }
    }

この問題について本当に提案が必要です。ここで少し立ち往生しています。

どんな助けでも大歓迎です。ありがとうございました

4

2 に答える 2

1

等高線を使用して応答マップを作成します。DrawContourshole_color=external_color>0 で使用します。これまたはこれを読んでください。サンプルコード:

cv::Mat responsemap = cv::Mat::zeros(height, width, CV_8UC1);
cv::DrawContours(responsemap, contours, external_color, hole_color, max_level, 1, 8);
if (responsemap.at<uchar>(y,x)!=0) std::cout<<"contour area";

応答マップに中心のみを印刷する必要がある場合は、それらを手動で設定します。

于 2013-05-17T15:36:01.137 に答える
0

点字を認識しようとしているようですね。

点字の形をしたマスクを作成するのはどうでしょうか。点があるかもしれないところは白で、予期しないところは黒です。何かのようなもの

    cv::Mat mask = cv::Mat(img.rows, img.cols, CV_8UC1, CV:RGB(0,0,0));
    cv::Mat out = cv::Mat(img.rows, img.cols, CV_8UC1, CV:RGB(0,0,0));
    cv::circle(mask, cv::Point(X,Y),10, CV_RGB(255,255,255),-1);
    (...)
    img.copyTo(out,mask);

したがって、画像と同じサイズとタイプの 2 つの黒いマットを作成し ( img)、マスク上の点字を期待するポイントに白い円を描きます。最後に、入力マット、出力マット、およびマスクを受け取る cv::copyTo を使用します。

この新しい画像で、輪郭検出を実行します。その結果、期待する場所にのみドットが検出されます。

于 2013-05-17T15:57:26.337 に答える