Inconsistent return values on pixel access.

asked 2017-05-10 10:13:10 -0500

bhornde gravatar image

updated 2017-05-10 10:41:03 -0500

Hello Community. I've got that litte snipped here. As you can see, Im accessing the pixel value kind of block-wise and use the columns pixel values as bits for a unsigned int. Block number and unsigned int serve as coordinates for another pixel in another image, set to 255.

cv::Mat1b devideAndConquer(const cv::Mat1b &raw, cv::Size2i &blockCount, cv::Size2i &blockSize){
    int wordBlockSize = std::pow(2,blockSize.height);
    cv::Mat1b word = cv::Mat1b::zeros(blockCount.width,wordBlockSize);
    for(uint8_t b = 0; b < blockCount.width; ++b) {
        for (uint8_t w = 0; w < blockSize.width; ++w) {
            unsigned int n = 0;
            for (uint8_t h = 0; h < (blockSize.height); ++h) {
                std::cout << (int)(raw.at<uchar>(b*blockSize.width+w,h));
                n = (n << 1) + (raw.at<uchar>(b*blockSize.width+w,h) > 0 ? 1 : 0);
            }
            std::cout <<":"<< n << "\t";
            word.at<uchar>(b,n) = 0xFF;
        }
    }
    std::cout << std::endl;
    return word;
}

I've tested everything. After hours of debugging I've found the following: Sometimes the return value of raw.at<uchar>(b*blockSize.width+w,h) is inconsistent between calls of devideAndConquer. I used this Code to test my assumptions:

cv::Size2i blockCount(13,1);
blockSize.height = 10;
blockSize.width = 16;
cv::Mat1b dummy(blockCount.height*blockSize.height,blockCount.width*blockSize.width);
do{
    cv::randu(dummy, 0, 2);
} while(cv::countNonZero(dummy) == 0);
do{
    cv::Mat1b a = devideAndConquer(dummy,blockCount,blockSize);
    cv::Mat1b b = devideAndConquer(dummy,blockCount,blockSize);
    cv::Mat1b c;
    cv::compare(a,b,c,CV_COMP_BHATTACHARYYA);
    cv::imshow("Window",c);
    cv::waitKey();
}while(cv::countNonZero(c) != 0);

In theses inconsistend cases, the output of the first call for one block is 0000000000:0, on the second call its 255000000000:512. So the return value of on .at call that should be 0 is 255. dummy isn't touched. When I CV_COMP_BHATTACHARYYA on the Dummy before the calls and after the Calls, the result is 0 nonZero Pixels. On 3th and 4th call, even more values are flipped but they are consistently flipped.

Do I miss something? Have I made an error? Or is there some bogus magic happening thats flipping pixels? Latest OpenCV 2.4 and 3.2 (both causing the same error) is used on an MacBookPro (13", Mid2011) with 4GB RAM and i7.

edit retag flag offensive close merge delete

Comments

word.data[(b*word.cols)+n] = 0xFF; helps a bit... word.at(b,n) = 0xFF somehow sets raw.at<uchar>(b*blockSize.width+w,0) = 0xFF, but only inside the scope of the function. Idk.

bhornde gravatar imagebhornde ( 2017-05-10 15:05:11 -0500 )edit

your dummy Mat is [13x16, 1x10].

now look at, how you access it:

(raw.at<uchar>(b*blockSize.width+w,h));

you probably confuse rows and cols here (it's mat.at(y,x) in opencv)

berak gravatar imageberak ( 2017-05-11 01:27:44 -0500 )edit

@berak isn't opencv row-col -> mat.at(row,col)?

bhornde gravatar imagebhornde ( 2017-05-12 04:58:08 -0500 )edit

yes, exactly. row==y, col==x. you got it in reverse, imho. (thus it's out-of-bounds)

also Mat(H,W,Type)

in general, you should avoid writing per-pixel loops like that. what is your code trying to achieve ?

berak gravatar imageberak ( 2017-05-12 05:12:02 -0500 )edit