OpenCV C++遍历图像像素异常:仅部分区域颜色修改生效
问题:OpenCV修改图像颜色仅部分区域生效
我用C++结合OpenCV尝试修改图像颜色,但修改并未应用到整个图像区域。为测试问题,我尝试将图像所有像素设置为固定颜色(36, 81, 214),对于一张360×600的图像,因padding只处理全部358行,但仅前150列生效。我添加了final_i和final_j变量验证循环变量是否到达358、598,结果变量确实到达了对应值,但为何仅部分区域颜色被修改?
代码片段
Mat apply_convolution_kernel(Mat img_color, int kernel[][3], int kernel_size){ int rows = img_color.rows; int cols = img_color.cols; Mat result = Mat(rows,cols, CV_32SC3, 0.0); cout<<img_color.rows<<" "<<img_color.cols<<endl; cout<<result.rows<<" "<<result.cols<<endl; int final_i = 0; int final_j = 0; // apply the kernel operator int aux_size = kernel_size / 2; // e.g for 3 x 3 kernel, we need [3/2] = 1 auxiliary padding for(int i=aux_size;i<rows - aux_size;i++){ for(int j = aux_size;j<cols - aux_size;j++){ Vec3b & pixel_from_res = result.at<Vec3b>(i,j); pixel_from_res[0] = 36; pixel_from_res[1] = 81; pixel_from_res[2] = 214; final_i = i; final_j = j; } } cout<<"final i: "<< final_i << " final j: "<<final_j<<endl; return result; } int main() { cout << "Start" << endl; Mat img_color = imread("sakura.jpg", 1); int conv_size = 3; int conv_operator[3][3] = { {0, 1, 0}, {1, 4, 1}, {0, 1, 0} } ; Mat m1 =apply_convolution_kernel(img_color, conv_operator,3); imwrite("filter.jpg", m1); return 0; }
问题原因与解决方法
核心问题:图像类型与像素访问类型不匹配
你创建的结果图像result是CV_32SC3类型(3通道32位有符号整数,每个像素占12字节),但访问像素时却用了Vec3b——这个类型对应8位无符号三通道(CV_8UC3,每个像素占3字节)。
这种类型不匹配会导致内存访问错位:每读取4个Vec3b对应的内存,才相当于1个CV_32SC3像素的内存。反映到图像上,就是实际修改的列数只有原列数的1/4(600÷4=150),和你看到的现象完全吻合。
解决方法
有两种可行的修正方式:
统一图像类型为8位无符号(推荐)
创建结果图像时,使用和原图一致的CV_8UC3类型,或者直接显式指定:Mat result = Mat(rows, cols, CV_8UC3, Scalar(0, 0, 0));这种方式也符合
imwrite的要求(imwrite默认只支持8位无符号类型的图像保存,避免后续保存时出现颜色失真或异常)。匹配像素访问类型
如果坚持使用CV_32SC3类型的结果图,需要用对应Vec3i类型访问像素:Vec3i &pixel_from_res = result.at<Vec3i>(i,j); pixel_from_res[0] = 36; pixel_from_res[1] = 81; pixel_from_res[2] = 214;
内容的提问来源于stack exchange,提问作者dacian
相关产品推荐
相关产品推荐

