opencv从入门到放弃|opencv C艹(色彩空间转换,像素最值,二值化,LUT)

色彩空间 【opencv从入门到放弃|opencv C艹(色彩空间转换,像素最值,二值化,LUT)】RGB,RGBA,YUV(亮度,红色分量与亮度信号的插值,蓝色与亮度的插值),HSV(色度,饱和度,亮度)。。。。。

void cv::cvtColor ( InputArraysrc, OutputArraydst, intcode, intdstCn = 0 ) // 数据类型转换 void cv::Mat::convertTo ( OutputArraym, intrtype, doublealpha = 1, doublebeta = 0 )const

改变色彩空间,前两个参数用于输入图像,目标图像,第三个参数指明转换的色彩空间,第四个参数默认就行。。需要注意的是该函数变换前后的图像取值范围
8位无符号图像的像素为0 - 255。CV_8U
16 无符号图像的像素为 0-65535. CV_16U
32 位浮点图像的像素为 0-1 ,
因此一定要注意目标图像的像素范围.在线性变换的情况下,范围问题不需要考虑,目标图像的像素不会超出范围。如果在非线性变换的情况下,那么应将输入 RGB 图像归一化到适当的范围以内来获得正确的结果,例如将 8位无符号图像转成 位32浮点图像 需要先将图像像素通过除以 255 缩放0-1 范围内 以防止产生错误结果.
opencv从入门到放弃|opencv C艹(色彩空间转换,像素最值,二值化,LUT)
文章图片

数据类型转换,参数为输出图像,转换图像的目标类型,alpha ,beta缩放因子,偏置因子。
m ( x , y ) = s a t u r a t e c a s t < r t p y e > ( α ( ? t h i s ) ( x , y ) + β ) m(x,y) = saturate_cast(\alpha(*this)(x,y) + \beta) m(x,y)=saturatec?ast(α(?this)(x,y)+β)
转换方式就是线性变换,按照指定的类型输出。
#include #include #include #include using namespace std; using namespace cv; int main(int argc, char *argv[]) { system("color E"); Mat img = imread("D:\\壁纸\\2k.jpg"); cout<opencv从入门到放弃|opencv C艹(色彩空间转换,像素最值,二值化,LUT)
文章图片

threshold() 函数全局就用一个阈值,实际上,由于光照,阴影的影响,全局只有一个i阈值是不合理的。adativeThershold() 提供了两个局部自适应阈值的二值化方法。
void cv::adaptiveThreshold ( InputArraysrc, // 只能是CV_8U OutputArraydst, doublemaxValue,// 二值化的最大值 intadaptiveMethod, // 自适应阈值的方法两种。高斯法或均值法 intthresholdType, // 二值化的标志,只能是BINART OR BINARY_INV 两种 intblockSize, // 自适应确定阈值的邻域,3,5,7奇数 doubleC // 平均值或加权平均值种减去的常数,可正可负 ) int main() { Mat img = imread("lena.png"); Mat gray; cvtColor(img, gray, COLOR_BGR2GRAY); Mat img_B, img_B_V, gray_B, gray_B_V, gray_T, gray_T_V, gray_TRUNC; //彩色图像二值化 threshold(img, img_B, 125, 255, THRESH_BINARY); threshold(img, img_B_V, 125, 255, THRESH_BINARY_INV); imshow("img_B", img_B); imshow("img_B_V", img_B_V); //灰度图BINARY二值化 threshold(gray, gray_B, 125, 255, THRESH_BINARY); threshold(gray, gray_B_V, 125, 255, THRESH_BINARY_INV); imshow("gray_B", gray_B); imshow("gray_B_V", gray_B_V); //灰度图像TOZERO变换 threshold(gray, gray_T, 125, 255, THRESH_TOZERO); threshold(gray, gray_T_V, 125, 255, THRESH_TOZERO_INV); imshow("gray_T", gray_T); imshow("gray_T_V", gray_T_V); //灰度图像TRUNC变换 threshold(gray, gray_TRUNC, 125, 255, THRESH_TRUNC); imshow("gray_TRUNC", gray_TRUNC); //灰度图像大津法和三角形法二值化 Mat img_Thr = imread("threshold.png", IMREAD_GRAYSCALE); Mat img_Thr_O, img_Thr_T; threshold(img_Thr, img_Thr_O, 100, 255, THRESH_BINARY | THRESH_OTSU); threshold(img_Thr, img_Thr_T, 125, 255, THRESH_BINARY | THRESH_TRIANGLE); imshow("img_Thr", img_Thr); imshow("img_Thr_O", img_Thr_O); imshow("img_Thr_T", img_Thr_T); //灰度图像自适应二值化 Mat adaptive_mean, adaptive_gauss; adaptiveThreshold(img_Thr, adaptive_mean, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 55, 0); adaptiveThreshold(img_Thr, adaptive_gauss, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 55, 0); imshow("adaptive_mean", adaptive_mean); imshow("adaptive_gauss", adaptive_gauss); waitKey(0); return 0; }

LUT(显示查找表)
前面介绍的阈值比较方法都只有一个阈值,需要与多个阈值比较,就用LUT,一个像素灰度值的映射表,,它以像索灰度值作为索引,以灰度值映射后的数值作为表中的内容。
void cv::LUT ( InputArraysrc,// 输入图像矩阵,只能是cv_8u,可以多通道 InputArraylut,// 1*256的像素灰度值的查找表,单通道或多通道 OutputArraydst// 输出类型与LUT 的类型一致,将灰度值映射到了新的空间种 ) #include #include #include #include using namespace std; using namespace cv; int main() { //LUT查找表第一层 uchar lutFirst[256]; for (int i = 0; i < 256; i++) { if (i <= 100) lutFirst[i] = 0; if (i > 100 && i <= 200)// 就是原图像的i像素,映射为我们指定的。 lutFirst[i] = 100; if (i > 200) lutFirst[i] = 255; } Mat lutOne(1, 256, CV_8UC1, lutFirst); //LUT查找表第二层 uchar lutSecond[256]; for (int i = 0; i < 256; i++) { if (i <= 100) lutSecond[i] = 0; if (i > 100 && i <= 150) lutSecond[i] = 100; if (i > 150 && i <= 200) lutSecond[i] = 150; if (i > 200) lutSecond[i] = 255; } Mat lutTwo(1, 256, CV_8UC1, lutSecond); //LUT查找表第三层 uchar lutThird[256]; for (int i = 0; i < 256; i++) { if (i <= 100) lutThird[i] = 100; if (i > 100 && i <= 200) lutThird[i] = 200; if (i > 200) lutThird[i] = 255; } Mat lutThree(1, 256, CV_8UC1, lutThird); //拥有三通道的LUT查找表矩阵 vector mergeMats; mergeMats.push_back(lutOne); mergeMats.push_back(lutTwo); mergeMats.push_back(lutThree); Mat LutTree; merge(mergeMats, LutTree); // 通道合并 //计算图像的查找表 Mat img = imread("lena.png"); if (img.empty()) { cout << "请确认图像文件名称是否正确" << endl; return -1; } Mat gray, out0, out1, out2; cvtColor(img, gray, COLOR_BGR2GRAY); LUT(gray, lutOne, out0); LUT(img, lutOne, out1); LUT(img, LutTree, out2); imshow("out0", out0); imshow("out1", out1); imshow("out2", out2); waitKey(0); return 0; }

可以看到,每个通道的像素都映射到了我们的规定值。
opencv从入门到放弃|opencv C艹(色彩空间转换,像素最值,二值化,LUT)
文章图片

总结
函数 说明
cvtColor 色彩空间转换
converTo 数据类型转换
saturate_cast() 缩放到标准
split 通道的分割
merge 通道的合并
minMaxLoc 像素最大最小值与位置
mean 平均值
meanStdDev 平均值加标准差
max/min 比较两幅图像的较大较小值
bitwise_and/or/xor/not 两幅图像素之间的逻辑操作
threshold 二值化
adaptiveThreshold 局部自适应二值化
LUT 灰度值映射,多阈值
// 构建一个掩模 Mat src1 = Mat::zeros(Size(512, 512), CV_8UC3); Rect rect(100, 100, 300, 300); // x,y,w,h src1(rect) = Scalar(255, 255, 255); // 此范围内赋值,构建一个掩模

    推荐阅读