我正在尝试将图像划分为网格,并保存单个片段。此刻,我循环浏览零件号并得到一个子图像,然后将其保存。
有人可以解释如何正确获取子图像吗?我一直在关注stackoverflow上的类似文章,但是我的代码始终使断言失败,该断言检查子图像与原始图像的界限。
int unitWidth = image.rows / n;
int unitHeight = image.cols / n;
for(int i=0; i<n; i++) {
//Take the next tile in the nxn grid. Unit is the width and height of
//each tile. i%n and i/n are just fancy ways of a double x,y for loop
Mat subImage = image(Rect((i % n) * unitWidth, (i / n) * unitHeight, unitWidth,unitHeight));
ostringstream oss;
oss << i << "_" << n << ".jpg";
string name = oss.str();
imwrite(name, subImage);
}
ps第一个子图像不会破坏程序,但是第二个图像会破坏程序(对于2x2网格,因此是末段)。我将子图像缩短了10个,但这仍然损坏了机器。
最佳答案
以下是固定的代码,可将图像分成nxn个图块。
首先,您对unitWidth
和unitHeight
的计算不正确,这是断言失败的原因。它应该是:
int unitWidth = image.cols / n; // you had image.rows / n;
int unitHeight = image.rows / n; // " " image.cols / n;
此外,如果要进行nxn slice ,则需要循环n ^ 2次,而不仅仅是n次。
最简单的方法是只有两个循环,一个在另一个循环内,一个循环行n次,另一个循环列n次。
for(int i = 0; i < n; i++) { //i is row index
// inner loop added so that more than one row of tiles written
for(int j = 0; j < n; j++) { // j is col index
//Take the next tile in the nxn grid. Unit is the width and height of
//each tile. i%n and i/n are just fancy ways of a double x,y for loop
// Mat subImage = image(Rect((i % n) * unitWidth, (i / n) * unitHeight, unitWidth, unitHeight));
// I didn't understand the above line, as ((i % n)==i and (i / n)==0.
//
Mat subImage = image(Rect(j * unitWidth, i * unitHeight, unitWidth, unitHeight));
ostringstream oss;
oss << i << "_" << j << ".jpg";
string name = oss.str();
imwrite(name, subImage);
}
}
调试这种代码的最简单方法是将Rect设置为一个单独的对象,以便您可以打印出其x,y,width,height并根据OpenCV断言消息进行检查。
您是否已在 Debug模式下编译代码?
cv::Rect roi(j * unitWidth, i * unitHeight, unitWidth, unitHeight);
cout << "(i, j) = (" << i << ", " << j << ")" << endl;
cout << "(i %n) = " << i%n << endl;
cout << "(i/n) = " << i/n << endl;
cout << "roi.x = " << roi.x << endl;
cout << "roi.y = " << roi.y << endl;
cout << "roi.width = " << roi.width << endl;
cout << "roi.height = " << roi.height << endl;
Mat subImage = image(roi);