颜色理论与实验(OpenCV)
内容仅作记录。
1. 理论部分
1.1 光谱图
颜色 | 波长 λ | 频率 f |
红色 | 约 625 ~ 740 nm | 约 480 ~ 405 THz |
橙色 | 约 590 ~ 625 nm | 约 510 ~ 480 THz |
黄色 | 约 565 ~ 590 nm | 约 530 ~ 510 THz |
绿色 | 约 500 ~ 565 nm | 约 600 ~ 530 THz |
蓝色 | 约 485 ~ 500 nm | 约 620 ~ 600 THz |
靛色 | 约 440 ~ 485 nm | 约 680 ~ 620 THz |
紫色 | 约 380 ~ 440 nm | 约 790 ~ 680 THz |
1.2 三原色
- 光学三原色(RGB): 红、绿、蓝。光学三原色混合后,组成显示屏显示颜色,三原色同时相加为白色,白色属于无色系(黑白灰)中的一种。
(红)+(绿)=(黄)= (白) - (蓝)
(蓝)+(绿)=(青)= (白) - (红)
(红)+(蓝)=(品红)= (白) - (绿)
(绿)+(蓝)+(红)=(白)
光学三原色(加法混色)
- 颜料三原色(CMYK): 品红、黄、青。颜料三原色可以混合出所有颜料的颜色,同时相加为黑色,黑白灰属于无色系。
(青)+(品红)=(蓝)= (黑)-(黄)
(品红)+(黄)=(红)= (黑)-(青)
(黄)+(青)=(绿)= (黑)-(品红)
(青)+(品红)+(黄)=(黑)
颜料三原色(减法混色)
1.3 颜色空间
- RGB彩色空间: 包含红(Red)、绿(Green)、蓝(Blue)三个分量;
- NTSC彩色空间: NTSC在美国用于电视系统,包含亮度(Y)、色调(I)、饱和度(Q)三个分量;
- YCbCr彩色空间: YCbCr彩色空间广泛应用与数字视频,包含亮度(Y)、蓝色分量和一个参考值的差(Cb)、红色分量和一个参考值的差(Cr)三个分量;
- HSL、HSV(HSB)彩色空间: 包含色调(Hue)、饱和度(Saturation)、亮度(Lightness)、数值/明度(Value, Brightness)分量;
- CMY、CMYK彩色空间: 包含青(C)、品红(M)、黄(Y)、黑(K)分量,通常用于印刷,为生成纯正的黑色,添加黑色分量;
- HSI彩色空间: 包含色度(Hue)、饱和度(saturation)、亮度(intensity)三个分量;
RGB色彩立方体
CMYK色彩立方体
HSL和HSV色彩模型
HSI色彩模型
1.4 颜色空间转换
1.4.1 RGB与NTSC互转
转换 | 计算公式 |
---|---|
RGB2NTSC | ![]() |
NTSC2RBG | ![]() |
1.4.2 RGB与NTSC互转
转换 | 计算公式 |
---|---|
RGB2YCbCr | ![]() |
1.4.3 RGB与CMY互转
转换 | 计算公式 |
---|---|
RGB2CMY | ![]() |
1.4.4 RGB与HSI互转
转换 | 计算公式 |
---|---|
RGB2HSI | ![]() ![]() ![]() |
HSI2RBG ![]() |
![]() |
HSI2RBG ![]() |
![]() |
HSI2RBG ![]() |
![]() |
2. 实验部分
2.1 提取中间绿色区域
cv::Mat img;
if (srcimg.channels() == 3) {
cv::Mat bgr[3];
cv::split(srcimg, bgr);
//img = bgr[2];
img = bgr[1] - bgr[2];
cv::imwrite("D:/debug/img.bmp", img);
cv::imwrite("D:/debug/bgr0.bmp", bgr[0]);
cv::imwrite("D:/debug/bgr1.bmp", bgr[1]);
cv::imwrite("D:/debug/bgr2.bmp", bgr[2]);
}
else {
img = srcimg;
}
src | b | g | r | g - r |
---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
2.2 提取中间圆孔
如上图,基于R通道,阈值化后找霍夫圆
//找霍夫圆
std::vector<cv::Vec3f> cir;
cv::HoughCircles(img, cir, cv::HOUGH_GRADIENT, 1, 10, 100, 30, 10, 30);
//srcimg.copyTo(dstimg);
cout << "检测到了 " << cir.size() << " 个圆!" << endl;
for (size_t i = 0; i < cir.size(); i++) {
cv::Vec3f cc = cir[i];
cout << "第 " << i << " 个圆的圆心和半径分别为: " << cv::Point(cc[0], cc[1]) << " 和" << cc[2] << endl;
circle(dstimg, cv::Point(cc[0], cc[1]), cc[2], cv::Scalar(255, 255, 0), 2, cv::LINE_AA);
circle(dstimg, cv::Point(cc[0], cc[1]), 1, cv::Scalar(255, 255, 0), 2, cv::LINE_AA);
}
cv::imwrite("D:/debug/circle_all.bmp", dstimg);
examples |
---|
![]() |
![]() |
![]() |
![]() |
![]() |
参考资料
[1] R.C.冈萨雷斯, P.温茨. 数字图象处理[M]. 科学出版社, 1981.
[2] https://ws.wiki.fallingwaterdesignbuild.com/wiki/颜色
[3] https://baike.baidu.com/item/三原色/764849?fr=aladdin
[4] http://adobephotoshop.blog.hexun.com/15935542_d.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?