Ask Your Question
0

how to scan lines vertically?

asked 2017-02-10 02:38:57 -0600

zms gravatar image

Hi, Currently im scanning lines in a binary image. The thing is i wanted to scan vertically yet i only found out that the for loop is only scanning it vertically. Here is the example of the code. Is there any way that i could scan the image vertically? I did swap the x and y together with rows and cols but it does not work.

for( int y=0; y< frame_gray.rows; y+=10){
    for (int x=0;x< frame_gray.cols;x+=1){

        if (frame_gray.at<uchar>(y,x)==0)
        {  cout << "0 binary=" << endl;}

        else
        {  cout << "1 binary=" << endl;}
        //waitKey(0);

    }

    cout << "new pixel line" << endl;
}
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
0

answered 2017-02-10 03:23:44 -0600

kbarni gravatar image

Swapping the two for loops should work:

for (int x=0;x< frame_gray.cols;x+=1){
    for( int y=0; y< frame_gray.rows; y++){
        cout<<"pixel at X="<<x<<" and y="<<y<<" is: "<<frame_gray.at<uchar>(y,x);
        if (frame_gray.at<uchar>(y,x)==0)
        {  cout << " (black)" << endl;}

        else
        {  cout << " (white)" << endl;}
        //waitKey(0);

    }

    cout << "new pixel column: "<<x << endl;
}

In the meantime, as long as it's possible, you should use line-by-line processing and line pointers. It's faster than direct element access with image.at<type>(y,x).

edit flag offensive delete link more

Comments

hi, it did worked as per suggest above, but may i know what do u mean by 'you should use line-by-line processing and line pointers. It's faster than direct element access with image.at<type>(y,x).'

zms gravatar imagezms ( 2017-02-13 01:54:22 -0600 )edit

I wanted to say that it's faster to process the image horizontally (one line after the other) than vertically (one column after the other). The code for line by line processing should be:

for(y=0;y<img.rows;y++){
    uchar *p=img.ptr(y);    //p is the pointer to line y
    for(x=0;x<img.cols;x++){
       cout<<p[x]<<endl;    //same but faster than img.at<uchar>(y,x)
    }
}
kbarni gravatar imagekbarni ( 2017-02-13 03:09:35 -0600 )edit
0

answered 2017-02-10 04:35:19 -0600

updated 2017-02-10 04:54:02 -0600

The 'efficient' way of scanning an image is to iterate over rows, as described here:

void ScanImageAndDoYourStuff(Mat& I)
{
    // accept only 1-channel char type matrices
    CV_Assert(I.type() == CV_8UC1);

    int nRows = I.rows;
    int nCols = I.cols;

    int i,j;
    uchar* p;
    for( i = 0; i < nRows; i+=10)
    {
        p = I.ptr<uchar>(i);
        for ( j = 0; j < nCols; ++j)
        {
            // do your stuff, eg.
            if (p[j]==0) cout << "0 binary=" << endl;
            else cout << "1 binary=" << endl;
            // p[j] is now same as I.at<uchar>(i,j), but accessing it sequentially is muuuuch faster
        }
    }
}

If you need to scan columns, just transpose (cv::transpose) your image (effcient way of rotating in your case) and then your columns will become rows. Does it make sense?

PS. As described in the document mentioned above, using cv::Mat::at<T>(u,v) is not efficient -especially for scanning whole image.

edit flag offensive delete link more

Comments

There is a typo in your code:

i+=10 should be i++

in my opinion.

Eduardo gravatar imageEduardo ( 2017-02-10 07:21:18 -0600 )edit

It's actually not a typo. It's just to match the example code in the question: for( int y=0; y< frame_gray.rows; y+=10) {...}

mstankie gravatar imagemstankie ( 2017-02-10 08:23:28 -0600 )edit

Indeed, should have read more carefully.

Eduardo gravatar imageEduardo ( 2017-02-10 09:49:20 -0600 )edit

the y+=10 is actualy, I'm scanning the line with difference of 10 pixel line spacing (sampling on the 10th pixel line) and i think it does not affect the direction of the line scanning? Is the y+=10 gonna effect the direction of the line scanning? :-?

zms gravatar imagezms ( 2017-02-13 01:23:00 -0600 )edit

I do not think the y+=10 can be the reason of vertical scanning not working in your case. Try:

cv::Mat frame_gray_rot;
cv::transpose(frame_gray, frame_gray_rot);
ScanImageAndDoYourStuff(frame_gray_rot);

Doesn't it work?

mstankie gravatar imagemstankie ( 2017-02-13 03:36:27 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-02-10 02:38:57 -0600

Seen: 1,485 times

Last updated: Feb 10 '17