Access of reduced image vectors [closed]

asked 2013-03-03 19:51:08 -0600

Hi All,

I am a newbie in OPENCV and tried to the similar things (discard margin sizes and compute for the effective width and height for a scanned document image) like the MATLAB code below

MATLAB CODE
====================================================================     
[height, width] = size(img_input);
img_colsum = sum(img_input,1);
idx_col_nonzero = find(img_colsum ~= 0);
img_width_effective = width+idx_col_nonzero(1)-idx_col_nonzero(end);    
img_rowsum = sum(img_input,2);    
idx_row_nonzero = find(img_rowsum ~= 0);
img_height_effective = height+idx_row_nonzero(1)-idx_row_nonzero(end);

I faced the difficulty of using the OEPNCV cv::reduce function, and probably also the way to access its elements. The strange thing that I saw in my following c++ code is that it works for one case but fails to work to the other case.

int find_idx_nonzero(cv::Mat &vec_input, cv::Mat &vec_idx) {
    int width = vec_input.cols;
    int height = vec_input.rows;
    int idx = 0;
    if (height == 1) {
        for (int w=0; w<width; w++) {
             if ( vec_input.at<float>(0,w) != 0 ) { vec_idx.at<int>(0,idx) = w; idx++; }
        }
    }
    else if (width == 1) {
        for (int h=0; h<height; w++) {
             if ( vec_input.at<float>(h,0) != 0 ) { vec_idx.at<int>(idx,0) = h; idx++; }
        }
    }
    return idx;
}

int main() {
    cv::Mat img_input; img_input = cv::imread("inputDoc.tif");
    int width = img_input.cols;
    int height = img_input.rows;
    cv::Mat img_colsum, img_rowsum;
    cv::reduce( img_input, img_colsum, 0, CV_REDUCE_SUM, CV_64FC1 );
    cv::Mat idx_col_nonzero( 1, width, CV_64F );
    int col_length;
    col_length = find_idx_nonzero( img_colsum, idx_col_nonzero );
    int img_width_effective = width+idx_col_nonzero.at<int>(0,0)-idx_col_nonzero.at<int>(0,col_length-1);
    cv::reduce( img_input, img_rowsum, 1, CV_REDUCE_SUM, CV_64FC1 );
    cv::Mat idx_row_nonzero( height, 1, CV_64F );
    int row_length;
    row_length = find_idx_nonzero( img_rowsum, idx_row_nonzero );
    int img_height_effective = height+idx_row_nonzero.at<int>(0,0)-idx_roonzero.at<int>(row_length-1,0);
    return 1;
}

And I have the following questions

 1. why does this code work OK for the column case but not the row case?   
 2. why *matrix.at(idx)* fails to work when I replace those matrix.at(0,idx) and (idx,0)? I saw [the OPENCV tutorial](http://opencv.jp/opencv-2.2_org/cpp/core_basic_structures.html?highlight=iterator#cv-mat-at) said that when a matrix is of 1D, then one can simply access the matrix element via *matrix.at(idx)*, instead of *matrix.at(idx,0)* or *matrix.at(0,idx)*. I tried this technique, but it does not work.
 3. Is there any quick rule of thumb to determine the data type in **.at<data type>**, especially I donot know in what situation to use what data type. For example, in the above code if I use *val_idx.at<float>(idx,0)* instead, the answer turns to be wrong, but I donot know why... 
 4. Why the size of img_rowsum and img_colsum are 1D, but I output them using cout<< img_colsum <<endl; I saw the output data is of the format like [0,0,0,1,0,2,...]?
 5. If I transpose the img_rowsum vector (i.e. only use the upper branch in if-else), I got the right answer.

Sorry for too many questions. Any comments are welcome

edit retag flag offensive reopen merge delete

Closed for the following reason question is not relevant or outdated by sturkmen
close date 2020-12-14 01:13:16.215308