如何实现RGB图像各通道负片效果?OpenCV代码运行报错求助
问题排查与修正
错误原因分析
- 坐标访问顺序错误:OpenCV中
Mat.at<Type>(y, x)的参数顺序是行(y)在前,列(x)在后,你的代码里写反成(x,y),导致越界访问内存,触发-1073741819(内存访问违规)错误。 - 未检查图像加载状态:如果
imread加载图像失败(路径错误、文件不存在/损坏),myImage会是空矩阵,后续split操作会直接崩溃。 - 通道合并顺序错误:OpenCV默认图像通道是BGR顺序,你合并时把红通道放第一位,会导致最终图像颜色错乱。
- 缺少窗口阻塞函数:
imshow后没有调用waitKey(),窗口会瞬间关闭,无法看到结果。
修正后的代码
#include<iostream> #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/imgproc.hpp> using namespace cv; using namespace std; int main() { Mat myImage; String imgPath = "C:/Users/tusha/Desktop/ResearchPractise/testNegativeImage/RGB.jpg"; // 检查图像是否加载成功 myImage = imread(imgPath, IMREAD_COLOR); if (myImage.empty()) { cout << "无法加载图像,请检查路径或文件!" << endl; return -1; } Mat different_Channels[3]; split(myImage, different_Channels); Mat b = different_Channels[0]; Mat g = different_Channels[1]; Mat r = different_Channels[2]; // 处理红通道:修正坐标顺序为(y,x) for (int y = 0; y < myImage.rows; y++) { for (int x = 0; x < myImage.cols; x++) { uchar pixelr = r.at<uchar>(y, x); r.at<uchar>(y, x) = 255 - pixelr; } } // 处理绿通道 for (int y = 0; y < myImage.rows; y++) { for (int x = 0; x < myImage.cols; x++) { uchar pixelg = g.at<uchar>(y, x); g.at<uchar>(y, x) = 255 - pixelg; } } // 处理蓝通道 for (int y = 0; y < myImage.rows; y++) { for (int x = 0; x < myImage.cols; x++) { uchar pixelb = b.at<uchar>(y, x); b.at<uchar>(y, x) = 255 - pixelb; } } // 按BGR顺序合并通道,匹配OpenCV默认格式 vector<Mat> channels; channels.push_back(b); channels.push_back(g); channels.push_back(r); Mat negImage; merge(channels, negImage); namedWindow("Negative", WINDOW_NORMAL); imshow("Negative", negImage); // 阻塞窗口,等待按键输入后关闭 waitKey(0); destroyAllWindows(); return 0; }
额外优化建议
你可以用OpenCV的矩阵运算简化代码,避免嵌套循环,效率更高:
// 替换所有循环,直接对通道矩阵做运算 r = 255 - r; g = 255 - g; b = 255 - b;
甚至可以直接对整个图像做负片运算,无需拆分通道:
Mat negImage = 255 - myImage;
这样代码会更简洁高效。
内容的提问来源于stack exchange,提问作者Tushar Khurana
相关产品推荐
相关产品推荐

