本章的重点内容就是理解彩色模型, 就是在灰度图像的基础上添加了图像的通道数, 具体的变换与前面的知识类似.
第三版教材中图片下载地址: book images downloads
vs2019配置opencv可以查看:VS2019 & Opencv4.5.4配置教程
前情回顾:
数字图像处理第三章 灰度变换和空间滤波 学习笔记
数字图像处理第四章 频率域滤波 学习笔记
数字图像处理第五章 图像复原和重建(内容较简单,就没有详细记录笔记)
后续剧情:
数字图像处理 第七章 小波域多分辨率处理 学习笔记
数字图像处理 第九章 形态学图像处理 学习笔记
数字图像处理 第十章 图像分割 学习笔记
数字图像处理 第11章 表示和描述 学习笔记
基本概念:
本节介绍了几种模型: RGB模型, HSI模型, 并阐述了模型之间的转换方式
从RGB到HSI的转换:
H分量由下式得到:
H = { θ , B ≤ G 360 ? θ , B > G H=\left\{\begin{matrix} \theta,\quad\quad\quad B\leq G \\ 360-\theta,\quad B > G \end{matrix}\right. H={θ,B≤G360?θ,B>G?
其中,
θ = arccos ? { 1 2 [ ( R ? G ) + ( R ? B ) [ ( R ? G ) 2 + ( R ? B ) ( G ? B ) ] 1 / 2 } \theta=\operatorname{arccos}\left\{{\frac{\displaystyle{\frac{1}{2}}[(R-G)+(R-B)}{\displaystyle{\left[(R-G)^{2}+(R-B)(G-B)\right]^{1/2}}}}\right\} θ=arccos? ? ??[(R?G)2+(R?B)(G?B)]1/221?[(R?G)+(R?B)?? ? ??
饱和度分量由下式得到:
S = 1 ? 3 ( R + G + B ) [ m i n ( R , G , B ) ] S=1-\frac{3}{(R+G+B)}[\mathrm{min}(R,G,B)] S=1?(R+G+B)3?[min(R,G,B)]
强度分度由下式:
I = 1 3 ( R + G + B ) I=\frac{1}{3}(R+G+B) I=31?(R+G+B)
从HSI到RGB的转换就复杂一些, 需要考虑扇区范围. 这里就不贴出来了
基于一种指定的规则对灰度值赋以颜色的处理
指定一个灰度值作为分层, 大于该灰度值的部分赋以一种颜色, 小于该灰度值的部分赋以另一种颜色.
变换模型如同灰度变换:
g ( x , y ) = T [ f ( x , y ) ] g(x,y)=T{\big[}f(x,y){\big]} g(x,y)=T[f(x,y)]
给出校正函数再实现即可.
opencv分割起来很简单, 使用split
函数:
void test01(string path) {
Mat img = imread(path);
if (img.empty()) {
cout << "Error: unable to load the image\n";
return;
}
//cout << img.channels() << endl;
resize(img, img, Size(256, 256));
Mat hsvImg;
cvtColor(img, hsvImg, COLOR_BGR2HSV);
vector<Mat> hsvCh;
split(hsvImg, hsvCh);
imshow("h channel", hsvCh[0]);
imshow("s channel", hsvCh[1]);
imshow("v channel", hsvCh[2]);
waitKey(0);
}
opencv有很多实现方式, 这里使用Sobel算子来进行检测:
void test03(string path) {
Mat img = imread(path);
if (img.empty()) {
cout << "Error: unable to load the image\n";
return;
}
Mat gray_img;
// 如果不转成灰度图片, 就需要对三通道单独计算
cvtColor(img, gray_img, COLOR_BGR2GRAY);
//计算梯度
Mat gradientX, gradientY;
Sobel(gray_img, gradientX, CV_32F, 1, 0, 1);
Sobel(gray_img, gradientY, CV_32F, 0, 1, 1);
Mat gradientMag;
magnitude(gradientX, gradientY, gradientMag);
double threshold = 50.0;
cv::Mat edges;
cv::threshold(gradientMag, edges, threshold, 255, cv::THRESH_BINARY);
imshow("original", img);
imshow("gradientXY", edges);
waitKey(0);
}