简体   繁体   中英

scale pixels of an image using opencv library and c++

I'm trying to create simple 1D Barcode Reader using OpenCV 2.4.5 and Visual Studio 2010 Express.

Here is my code so far:

//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;

The Test Image is 100x100px Image with black and white pixels in following order (described as binary code for better understanding: 1=black,0=white) 10100<..white pixels..>00101

The reason I'm making this is simple...

Let's say I have an UPC Barcode which can be 81 pixels long. However, my loaded Image is over 1000 pixels in length.

To apply the detection and to compare my loaded image with the UPC pattern I have to scale the loaded image to correct pixel value first. ( I use the word "scale" ...because if I would just "resize" my image... it would cut off 919 pixels, making the detection impossible.)

  • I know that the loaded image is of factor 12,34 to UPC pattern (which is near 12....I don't care about the correct values now...all I care about is the implementation at the moment...)

    • So to achieve the scaling I have to count the occurence of each black and white pixel, save it in an array and then divide it with my factor to get the scaled value.

I'm facing the following problem using this implementation:

The occurences will be stored as following:

____[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)

But it should be:

____[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

I hope I provide enough information needed for answers.

Please help me out to correct my code. Best regards Ondrej

I think you should redo your for cycle. It is correct, but too complicated. The problem with your code is on this line:

buffer[col] = next_black_color;

The variable col is always increasing, so the updated color count is added to the new slot in array. You cannot have 97 at position 5 in you example, because given your code, at position 5, you only processed 5 pixels.

Another slight problem with your code is, that you have two mutually exclusive conditions. If color < 127 and color > 127. First of all, if color is < 127, the else means that color is >=127. The equal sign is important! Your code would fail, if all colors would be 127.

Following is rough draft of the algorithm:

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;

By no means it's complete. You will have to adapt to your needs. In the last if, we cannot compare last and current value directly, because 120 and 12 are both dark, but not same value. In your code replace the cout's with proper vector assignment, and don't forget the one outside the cycle. ;)

Regards,

jnovacho

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM