基础知识
我们熟知的颜色模式就是RGB(显示器发光三原色)和CMYK(颜料三原色)
而HSI是通过H(色调)S(饱和度)I(亮度)来决定图像的(这种图像模式在RGB模式为基础的显示器下显示效果不同)
详见Wiki百科
RGB转HSI的数学公式:
VisualStudio的C++项目下配置64位OpenCV步骤
- 在OpenCV.org下载某个版本的OpenCV的Windows的包,这里以3.4.10为例
下载下来发现是自解包,解压到某安装路径。
- 配置环境变量:
此电脑右键-高级系统设置-环境变量
在下半边的“系统变量”中修改Path的值,新建一条:安装目录\opencv\build\x64\vc15\bin
(这里注意你的实际vc版本)
在总的“系统变量”中新建一条名为OPENCV的项目,值为:安装目录\opencv\build
确定,应用。
- 新建项目:控制台应用程序
修改Debug版本为64位
- 右键项目-属性-VC++目录
修改项“包含目录”添加三项:opencv安装路径\opencv\build\include
及其子项
修改项“库目录”添加64位的库位置:安装路径\opencv\build\x64\vc15\bin
- 项目属性-链接器
修改:链接器-常规-附加库目录 中添加:安装路径\opencv\build\x64\vc15\lib
修改:链接器-输入-附加依赖项 中添加:opencv_world3410d.lib
注意
这里的opencv_world3410d.lib中的3410对应版本号,d对应debug模式,如果是3.4.11版本的release模式则为opencv_world3411.lib
确定,应用,配置完成。
RGB转换成HSI代码
#include <iostream>
#include <opencv2/opencv.hpp>
#define PI 3.1415926
using namespace std;
using namespace cv;
int main()
{
string path;
cout << "输入想要操作的图片的地址/名称(带后缀名)" << endl;
cin>>path;
Mat src = imread(path, 1);
if (src.empty())
cerr << "Error: Loading image" << endl;
Mat hsi(src.rows, src.cols, src.type());
float r, g, b, H, S, I, num, den, theta, sum, min_RGB;
for (int i = 0; i < src.rows; i++)
{
for (int j = 0; j < src.cols; j++)
{
b = src.at<Vec3b>(i, j)[0];
g = src.at<Vec3b>(i, j)[1];
r = src.at<Vec3b>(i, j)[2];
// 归一化
b = b / 255.0;
g = g / 255.0;
r = r / 255.0;
num = 0.5 * ((r - g) + (r - b));
den = sqrt((r - g) * (r - g) + (r - b) * (g - b));
theta = acos(num / den);
if (den == 0)
H = 0; // 分母不能为0
else
if (b <= g)
H = theta;
else
H = (2 * PI - theta);
min_RGB = min(min(b, g), r); // min(R,G,B)
sum = b + g + r;
if (sum == 0)
S = 0;
else
S = 1 - 3 * min_RGB / sum;
I = sum / 3.0;
H = H / (2 * PI);
// 将S分量和H分量都扩充到[0,255]区间以便于显示;一般H分量在[0,2pi]之间,S在[0,1]之间
hsi.at<Vec3b>(i, j)[0] = H * 255;
hsi.at<Vec3b>(i, j)[1] = S * 255;
hsi.at<Vec3b>(i, j)[2] = I * 255;
}
}
namedWindow("rgb_lwpImg", CV_WINDOW_AUTOSIZE);
namedWindow("hsi_lwpImg", CV_WINDOW_AUTOSIZE);
imshow("rgb_lwpImg", src);
imshow("hsi_lwpImg", hsi);
waitKey(0);
return 0;
}
实现效果
注意:RGB显示器无法显示出HSI模式的正确模样
还不快抢沙发