寻求遍历512x512图像的64x64分块嵌套循环解决方案
问题分析与解决方案:嵌套遍历图像分块时重复访问同一区域
你的代码核心问题出在像素访问时没有加上分块的起始偏移,导致每次内层循环都只读取图像左上角的64x64区域,完全没有用到外层循环的t_row和t_col变量。
问题根源
外层的t_row和t_col是每个64x64分块的起始坐标,但内层循环里你直接用row和col(范围0-63)作为像素的坐标:
Vec3b bgrPixel = sourceImage.at<Vec3b>(row, col);
这相当于每次都读取图像的(0,0)到(63,63)区域,完全没有偏移到当前分块的位置。
修正后的代码
只需要在像素坐标中加上外层循环的起始偏移t_row和t_col,就能正确遍历每个分块:
int main() { char imgName[] = "data/near.jpg"; //input1.jpg, input2.jpg, near.jpg, far.jpg Mat sourceImage = imread(imgName); resize(sourceImage, sourceImage, Size(512, 512)); // 遍历每个64x64分块的起始位置 for (int t_row = 0; t_row < sourceImage.rows; t_row += 64) { for (int t_col = 0; t_col < sourceImage.cols; t_col += 64) { // 遍历当前分块内的每个像素 for (int row = 0; row < 64; row++) { for (int col = 0; col < 64; col++) { // 加上分块起始偏移,定位到当前分块的像素 Vec3b bgrPixel = sourceImage.at<Vec3b>(t_row + row, t_col + col); cout << bgrPixel << endl; } } } } return 0; }
更简洁的优化方案(OpenCV ROI)
OpenCV支持直接通过**感兴趣区域(ROI)**来操作图像分块,代码会更简洁易读,不需要嵌套四层循环:
int main() { char imgName[] = "data/near.jpg"; Mat sourceImage = imread(imgName); resize(sourceImage, sourceImage, Size(512, 512)); const int blockSize = 64; for (int t_row = 0; t_row < sourceImage.rows; t_row += blockSize) { for (int t_col = 0; t_col < sourceImage.cols; t_col += blockSize) { // 定义当前分块的ROI Rect blockROI(t_col, t_row, blockSize, blockSize); Mat block = sourceImage(blockROI); // 遍历当前分块的像素(也可以用block.at<Vec3b>(row, col)直接访问) for (int row = 0; row < block.rows; row++) { for (int col = 0; col < block.cols; col++) { Vec3b bgrPixel = block.at<Vec3b>(row, col); cout << bgrPixel << endl; } } } } return 0; }
这种方式的好处是:如果后续图像尺寸不是blockSize的整数倍(比如500x500),block.rows和block.cols会自动适配剩余区域的大小,不需要额外判断边界。
内容的提问来源于stack exchange,提问作者Harrison Chong
相关产品推荐
相关产品推荐

