C++不使用OpenCV内置函数调整图像亮度代码异常排查
代码问题排查与修复
存在的问题
- 返回值错误:函数逻辑中处理好的结果存在
output变量中,但最终返回的是未修改的原输入图像img,外部调用该函数时拿到的永远是原图。 - 无符号数溢出导致阈值判断失效:
cv::Vec3b的元素类型是uchar(无符号8位整数,取值范围0~255),直接和int类型的num相加后赋值回uchar时会自动截断:- 相加结果超过255时会发生上溢回卷,比如
250 + 20得到的不是270,而是270%256=14,后续判断>255永远不成立 - 相加结果小于0时会发生下溢回卷,比如
10 - 20得到的不是-10,而是246,后续判断<0永远不成立
- 相加结果超过255时会发生上溢回卷,比如
- 硬编码使用
cv::Vec3b仅支持3通道彩色图像,输入单通道灰度图时会触发内存访问异常。
修复后的代码
cv::Mat adjustBrightness(cv::Mat img, int num){ cv::Mat output = cv::Mat::zeros(img.rows, img.cols, img.type()); int channel = img.channels(); for (int i = 0; i < img.rows; i++) { for (int j = 0; j < img.cols; j++) { for (int c = 0; c < channel; c++) { // 先转成int计算,避免溢出 int pixelVal = static_cast<int>(img.ptr<uchar>(i)[j * channel + c]) + num; // 截断到0~255范围 pixelVal = pixelVal > 255 ? 255 : (pixelVal < 0 ? 0 : pixelVal); // 赋值回输出图像 output.ptr<uchar>(i)[j * channel + c] = static_cast<uchar>(pixelVal); } } } cv::imshow("output", output); cv::waitKey(0); // 返回处理后的图像 return output; }
补充说明
如果仅需要处理3通道彩色图像,也可以保留cv::Vec3b的写法,只需要修改计算逻辑:
output.at<cv::Vec3b>(i,j)[c] = cv::saturate_cast<uchar>(static_cast<int>(img.at<cv::Vec3b>(i,j)[c]) + num);
cv::saturate_cast<uchar>会自动把int值截断到0~255范围,不需要额外写if判断。
内容的提问来源于stack exchange,提问作者wonki cho
相关产品推荐
相关产品推荐

