1 | initial version |
Very interesting question! I've been playing around and I've found a very surprising situation: the problems are caused by the clone() method. If you remove it, then everything is as expected.
But now the question is why? I have no idea, I'm really puzzled. In fact, I've updated the provided code and now shows the strange behavior - I hope some of the devs/gurus here can figure out what's going on:
void main(){
Mat imgRaw = imread("image.png", 0);
Mat comparison;
//sliding window fits once
Mat singleWindow = Mat(imgRaw, Rect(0, 0, 48, 96));
Mat singleWindow_clone = Mat(imgRaw, Rect(0, 0, 48, 96)).clone();
compare(singleWindow, singleWindow_clone, comparison, CMP_EQ);
if (countNonZero(comparison) == singleWindow.rows*singleWindow.cols){
cout << "singleWindow and singleWindow_clone are the same matrices" << endl;
}
//sliding window fits twice and the first fit is equal to the singleWindow
Mat doubleWindow = Mat(imgRaw, Rect(0, 0, 49, 96));
Mat doubleWindow_clone = Mat(imgRaw, Rect(0, 0, 49, 96)).clone();
compare(doubleWindow, doubleWindow_clone, comparison, CMP_EQ);
if (countNonZero(comparison) == doubleWindow.rows*doubleWindow.cols){
cout << "doubleWindow and doubleWindow_clone are the same matrices" << endl;
}
vector<float> singleDescri, doubleDescri, singleDescri_clone, doubleDescri_clone;
//standard HOG: block(16,16), bStride(8,8), cell(8,8), 9 bins
HOGDescriptor d(Size(48, 96), Size(16, 16), Size(8, 8), Size(8, 8), 9);
//using NO winStride, NO padding (takes just first window)
d.compute(singleWindow, singleDescri);
d.compute(doubleWindow, doubleDescri);
d.compute(singleWindow_clone, singleDescri_clone);
d.compute(doubleWindow_clone, doubleDescri_clone);
compare((Mat)singleDescri, (Mat)doubleDescri, comparison, CMP_EQ);
cout << "NO CLONE done, # of matches between HOG descr: " << countNonZero(comparison) << endl;
compare((Mat)singleDescri_clone, (Mat)doubleDescri_clone, comparison, CMP_EQ);
cout << "CLONE done, # of matches between HOG descr: " << countNonZero(comparison) << endl;
}
The output is this:
singleWindow and singleWindow_clone are the same matrices
doubleWindow and doubleWindow_clone are the same matrices
NO CLONE done, number of matches between HOG descriptors: 1980
CLONE done, number of matches between HOG descriptors: 1586
So as expected, using the ROI as it is or cloning it generate the same matrix content, but HOG descriptor over the matrices are different. So...maybe something related to matrix header when cloning?
2 | No.2 Revision |
Very interesting question! I've been playing around and I've found a very surprising situation: the problems are caused by the clone() method. If you remove it, then everything is as expected.
But now the question is why? I have no idea, I'm really puzzled. In fact, I've updated the provided code and now shows the strange behavior - I hope some of the devs/gurus here can figure out what's going on:
void main(){
Mat imgRaw img = imread("image.png", 0);
Mat comparison;
//sliding window fits once
Rect roiRect(0, 0, 64, 128);
//Taking ROIs (with and without cloning)
Mat singleWindow ROI = Mat(imgRaw, Rect(0, 0, 48, 96));
Mat(img, roiRect);
Mat singleWindow_clone ROI_clone = Mat(imgRaw, Rect(0, 0, 48, 96)).clone();
compare(singleWindow, singleWindow_clone, Mat(img, roiRect).clone();
//Check both ROIs are equal
compare(ROI, ROI_clone, comparison, CMP_EQ);
if (countNonZero(comparison) == singleWindow.rows*singleWindow.cols){
ROI.rows*ROI.cols){
cout << "singleWindow "ROI and singleWindow_clone ROI_clone are the same matrices" << endl;
}
//sliding window fits twice and the first fit is equal to the singleWindow
Mat doubleWindow = Mat(imgRaw, Rect(0, 0, 49, 96));
Mat doubleWindow_clone = Mat(imgRaw, Rect(0, 0, 49, 96)).clone();
compare(doubleWindow, doubleWindow_clone, comparison, CMP_EQ);
if (countNonZero(comparison) == doubleWindow.rows*doubleWindow.cols){
cout << "doubleWindow and doubleWindow_clone are the same matrices" << endl;
}
//Standard HOG computation, one single window
vector<float> singleDescri, doubleDescri, singleDescri_clone, doubleDescri_clone;
//standard HOG: block(16,16), bStride(8,8), cell(8,8), 9 bins
descriptor, descriptor_clone;
HOGDescriptor d(Size(48, 96), d(Size(roiRect.width, roiRect.height), Size(16, 16), Size(8, 8), Size(8, 8), 9);
//using NO winStride, NO padding (takes just first window)
d.compute(singleWindow, singleDescri);
d.compute(doubleWindow, doubleDescri);
d.compute(singleWindow_clone, singleDescri_clone);
d.compute(doubleWindow_clone, doubleDescri_clone);
compare((Mat)singleDescri, (Mat)doubleDescri, d.compute(ROI, descriptor);
d.compute(ROI_clone, descriptor_clone);
compare((Mat)descriptor, (Mat)descriptor_clone, comparison, CMP_EQ);
cout << "NO CLONE done, # "There are " << descriptor.size() - countNonZero(comparison)
<< " different components between both descriptors out of matches between HOG descr: " << countNonZero(comparison) << endl;
compare((Mat)singleDescri_clone, (Mat)doubleDescri_clone, comparison, CMP_EQ);
cout << "CLONE done, # of matches between HOG descr:
<< descriptor.size() << " << countNonZero(comparison) total components" << endl;
}
The output is this:
singleWindow and singleWindow_clone are the same matrices
doubleWindow and doubleWindow_clone are the same matrices
NO CLONE done, number of matches between HOG descriptors: 1980
CLONE done, number of matches between HOG descriptors: 1586
So as expected, using the ROI as it is or cloning it generate the same matrix content, but HOG descriptor over the matrices are different. So...maybe something related to matrix header when cloning?
EDIT: simpler code added