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