2013-05-22 28 views
1

我正嘗試使用OpenCV 2.4.5和Visual Studio 2010 Express創建簡單的1D條形碼讀取器。使用opencv庫和C++的圖像縮放像素

這裏是到目前爲止我的代碼:

//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 =白) ..white像素..> 00101

我做這個很簡單的原因...

比方說,我有一個UPC條碼可以是81個像素長。 但是,我加載的圖片長度超過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 

我希望我能提供足夠的答案信息。

請幫我解決我的問題。 祝你好運 Ondrej

+0

首先使用imread()從highgui模塊,cvLoadImage爲C API。 第二個你說的,那就是你的測試圖像中的0 - 黑色,1 - 白色。但條件是測試<127。 0,1都小於127,因此不起作用。將白色像素設置爲255(例如,使用閾值)或將條件設置爲正確的值。 – jnovacho

+0

已編輯的文章,一些單詞用更準確的含義替換,用cv :: imread代替cvLoadImage。感謝您的更正。我正在使用cvLoadImage,因爲cv :: imread不能以調試模式運行。 – Ondrej

+0

imread如何運行?有沒有可能,你沒有用調試符號編譯highgui? – jnovacho

回答

1

我認爲你應該重做你的週期。這是正確的,但太複雜。與你的代碼的問題是在這條線:

buffer[col] = next_black_color; 

變量山坳總是不斷增加,所以新的色數被添加到陣列的新插槽。在你的例子中,你不能在位置5有97,因爲給定你的代碼,在位置5,你只能處理5個像素。

你的代碼的另一個小問題是,你有兩個互斥的條件。如果顏色是< 127並且顏色大於127.首先,如果顏色是< 127,則其他顏色表示顏色大於等於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; 

並不意味着它是完整的。你將不得不適應你的需求。在最後一個,如果我們不能直接比較最後一個值和當前值,因爲120和12都是暗的,但是不是相同的值。在你的代碼中,用正確的向量賦值替換cout,並且不要忘記循環之外的那個。 )

問候,

jnovacho

+0

我現在就試一試,並在更新的代碼發佈後發佈。無論如何,使用vector而不是普通的int數組是個好主意,因爲我不必關心每次的大小和手動調整它的大小。感謝您的回覆jnovacho。 – Ondrej

+0

所以我試了你的代碼。它不起作用。我的意思是它的工作原理,但輸出結果與以前一樣。正如你已經指出的那樣,問題在於for循環本身。它使if條件貫穿,保存向量中僅一個位置的顏色,然後跳轉到新的位置,再次運行if語句並將結果保存到新數組中。現在想到的唯一可能是一個while循環。因此,我可以定義應該運行多久或直到應該運行並保存黑色顏色,例如...您怎麼看?問候,Ondrej – Ondrej

+0

你是對的,上面的代碼不會工作,我的壞。 我將運行一些測試並更新代碼。 同時看看運行長度編碼。這就是你正在尋找的。 – jnovacho