7

曲線 /path に沿ってピクセルにアクセスする解決策はありますか? LineIterator を使用してそれを行うことができますか

4

3 に答える 3

6

はい、CvLineIteratorメソッドを使用してピクセルにアクセスできます。

以下のリンクを参照してください。

http://opencv.jp/opencv-2.2_org/c/core_drawing_functions.html

于 2013-12-20T15:31:51.113 に答える
4

わかりました、パラメータ化できる接続された曲線に沿ってピクセルにアクセスする方法を次に示します。もっと効率的な方法があるかもしれませんが、これは非常に簡単です: ピクセルに 2 回アクセスしたり、ピクセルをスキップしたりしないように、パラメータ ステップで曲線をサンプリングするだけです。

サンプルとしてウィキペディアからパラメトリック関数を使用しました: http://en.wikipedia.org/wiki/Parametric_equation#Some_sophisticated_functions

ここに画像の説明を入力

int main()
{
cv::Mat blank = cv::Mat::zeros(512,512,CV_8U);

// parametric function:
// http://en.wikipedia.org/wiki/Parametric_equation#Some_sophisticated_functions
// k = a/b
// x = (a-b)*cos(t) + b*cos(t((a/b)-1))
// y = (a-b)*sin(t) - b*sin(t((a/b)-1))

float k = 0.5f;
float a = 70.0f;
float b = a/k;

// translate the curve somewhere
float centerX = 256;
float centerY = 256;

// you will check whether the pixel position has moved since the last active pixel, so you have to remember the last one:
int oldpX,oldpY;
// compute the parametric function's value for param t = 0
oldpX = (a-b)*cos(0) + b*cos(0*((a/b)-1.0f)) + centerX -1;
oldpY = (a-b)*sin(0) - b*sin(0*((a/b)-1.0f)) + centerY -1;

// initial stepsize to parametrize the curve
float stepsize = 0.01f;

//counting variables for analyzation
unsigned int nIterations = 0;
unsigned int activePixel = 0;

// iterate over whole parameter region
for(float t = 0; t<4*3.14159265359f; t+= stepsize)
{
    nIterations++;

    // compute the pixel position for that parameter
    int pX = (a-b)*cos(t) + b*cos(t*((a/b)-1.0f)) + centerX;
    int pY = (a-b)*sin(t) - b*sin(t*((a/b)-1.0f)) + centerY;

    // only access pixel if we moved to a new pixel:
    if((pX != oldpX)||(pY != oldpY))
    {
        // if distance to old pixel is too big: stepsize was too big
        if((abs(oldpX-pX)<=1) && (abs(oldpY-pY)<=1))
        {
            //---------------------------------------------------------------
            // here you can access the pixel, it will be accessed only once for that curve position!
            blank.at<unsigned char>((pY),(pX)) = blank.at<unsigned char>((pY),(pX))+1;
            //---------------------------------------------------------------

            // update last position
            oldpX = pX;
            oldpY = pY;

            activePixel++;  // count number of pixel on the contour
        }
        else
        {
            // adjust/decrease stepsize here
            t -= stepsize;
            stepsize /= 2.0f;

            //TODO: choose smarter stepsize updates
        }
    }
    else
    {
        // you could adjust/increase the stepsize here
        stepsize += stepsize/2.0f;

        //TODO: prevent stepsize from becoming 0.0f !!
        //TODO: choose smarter stepsize updates
    }

}
std::cout << "nIterations: " << nIterations << " for activePixel: " << activePixel << std::endl;

cv::imwrite("accessedOnce.png", blank>0);
cv::imwrite("accessedMulti.png", blank>1);

cv::waitKey(-1);
return 0;
}

これらの結果を与える:

一度アクセスされたピクセル:

ここに画像の説明を入力

複数回アクセスされたピクセル:

ここに画像の説明を入力

端末出力: nIterations: 1240 for activePixel: 1065

于 2013-12-20T19:24:52.877 に答える
4

これには組み込み関数はないと思います。最初に構造で線/曲線を定義しcv::Matてから、そこから先に進む必要があります。例を挙げて説明しましょう。

  1. 画像がcv::Mat input_imageあり、 を使用して、cv::HoughLinesDetectorに保存されている画像内の線を検出しcv::Mat hough_linesます。
  2. 次に、反復しhough_linesて入力する必要がありcv::Mat hough_Mat(cv::Size(input_image.size()))ます (元のデータに対して線を明るく表示したい場合は、BGR 画像に変換する必要があります。
  3. 次に、hough_Matどのピクセルがゼロより大きいかを単純に繰り返してから、 の同じ場所にアクセスしますinput_image

この例はハフ変換を使用した単純なものですが、元の画像に関する曲線のデータがある限り、他の曲線で使用できます。

HTH

于 2013-12-20T16:22:36.257 に答える