1

OpenCV 2.4.5 と Visual Studio 2010 Express を使用して、単純な 1D バーコード リーダーを作成しようとしています。

これまでの私のコードは次のとおりです。

//define Image path:
char* imageName = "D:\\Barcode Reader\\test3.jpg";
cv::Mat src = cv::imread(imageName);

if( !src.data )
{ return -1; }

//convert image to grayscale img:    
cv::Mat gray_image;
cvtColor (src, gray_image, CV_BGR2GRAY);

unsigned char color;
unsigned char next_black_color = 0;
unsigned char next_white_color = 0;
int buffer[500];

float factor = (float)gray_image.cols / (float)required_width;

//start to search for pixels from left to right (in the middle of the img):
unsigned char *position  = gray_image.ptr(gray_image.rows/2,0);

//iterate through the whole image length:
for (int col = 1; col <= gray_image.cols; col++)
{   
//...and store the pixel value in color variable for possible output (which would be like 0-127 for black colors and 127-255 for white colors:
    color = *position;
    position++;
//check the pixel value ( < 127 everything bellow has dark color):
    if (color < 127)
{
//...and after each position checked, go to next pixel and save the number of occurences of black pixels:

        next_black_color++;
        buffer[col] = next_black_color;
        std::cout << col << ": " << buffer[col] << " ";
}
else
{
//set the counter variable to null for the next occurence of black pixel:
        next_black_color = 0;
}
//the same goes for white pixels:
    if (color > 127)
{   
    next_white_color++;
    buffer[col] = next_white_color;
    std::cout << col << ": " << buffer[col] << " ";
}
else
{
    next_white_color = 0;
}
}

//show the results:
std::cout<<" Number of pixels in width = " << src.cols << std::endl <<
"Number of pixels in height = " << src.rows << std::endl;

cv::imshow("Normal Image", src);
cv::imshow("Gray Image", gray_image);

cv::waitKey(0);

return 0;

テスト画像は 100x100px で、黒と白のピクセルが次の順序で配置された画像です (理解を深めるためにバイナリ コードで記述: 1=黒、0=白) 10100<..白ピクセル..>00101

これを作った理由は単純で…

81 ピクセルの長さの UPC バーコードがあるとします。ただし、読み込まれた画像の長さが 1000 ピクセルを超えています。

検出を適用し、読み込まれた画像を UPC パターンと比較するには、最初に読み込まれた画像をスケーリングしてピクセル値を修正する必要があります。(「スケール」という言葉を使用しています...画像を単に「サイズ変更」すると... 919ピクセルが切り取られ、検出が不可能になるためです。)

  • ロードされた画像はUPCパターンに対して12,34倍であることを知っています(これは12に近いです....今は正しい値は気にしません...私が気にするのは現時点での実装だけです... )

    • したがって、スケーリングを実現するには、各黒と白のピクセルの発生をカウントし、それを配列に保存してから、係数で除算してスケーリングされた値を取得する必要があります。

この実装を使用して、次の問題に直面しています。

オカレンスは次のように保存されます。

____[Array]____
Position | Occurence
1 ......... 1 (First position with first black pixel)
2 ......... 1 (white)
3 ......... 1 (black)
4 ......... 1 (white pixels until next black pixel appears..)
5 ......... 2 (___Problem here!___ ... should be 94!)
6 ......... 3          .
. ......... .          .
100 ....... 100(end)

ただし、次のようにする必要があります。

____[Array]____
Position | Occurence
1 ......... 1  (First position with first black pixel)
2 ......... 1  (white)
3 ......... 1  (black)
4 ......... 94 (count all white pixels until black appears again)
5 ......... 1  (black)
6 ......... 1  (white)
7 ......... 1  (black) -> end

回答に必要な十分な情報を提供していただければ幸いです。

私のコードを修正するのを手伝ってください。よろしくオンドレイ

4

1 に答える 1

1

forサイクルをやり直すべきだと思います。正しいですが、複雑すぎます。コードの問題は次の行にあります。

buffer[col] = next_black_color;

変数colは常に増加しているため、更新された色数が配列の新しいスロットに追加されます。この例では、位置 5 に 97 を指定することはできません。これは、コードを指定すると、位置 5 で 5 ピクセルしか処理しなかったためです。

コードのもう 1 つの小さな問題は、相互に排他的な 2 つの条件があることです。If color < 127 and color > 127. まず、color < 127 の場合、else は color が >=127 であることを意味します。等号は重要です!すべての色が 127 になると、コードは失敗します。

以下は、アルゴリズムのラフ ドラフトです。

int arr[] = {0,0,180,180,180,180,180,180,180,180,180,0,0,0};
int size = 14;

bool last_dark = false;
bool current_dark = false;

if(arr[0] < 127){
    last_dark = true;
}

int counter = 0;
for(int i = 0; i < size; i++){
    if(arr[i] < 127){
        current_dark = true;
    } else {
        current_dark = false;
    }

            // is current pixel same shade as last?
    if(last_dark == current_dark){
        counter++;
    } else {
        cout << counter << endl;
        counter = 1; // the last color is already processed
    }
    last_dark = current_dark;
}
    // following line is important to get the last count
cout << counter << endl;

完成したわけではありません。あなたのニーズに適応する必要があります。最後の if では、120 と 12 はどちらも暗い値ですが、同じ値ではないため、前回の値と現在の値を直接比較することはできません。あなたのコードでは、cout を適切なベクトル割り当てに置き換え、サイクルの外側のものを忘れないでください。;)

よろしく、

ヨノバチョ

于 2013-05-22T14:26:40.867 に答える