二、C++ opencv 色彩学处理(灰度处理,色域处理,阈值处理,颜色通道)

1、灰度处理,很简单直接代码。

#include <opencv2/opencv.hpp>
#include <iostream>

int main(int argc, char const* argv[])
{
    cv::Mat img = cv::imread("D://RM//练习//灰度处理//opencv-logo.png", cv::IMREAD_GRAYSCALE);
    cv::imshow("hello", img);
    cv::waitKey();

    return 0;
}

2、图像色彩空间转换

1)色彩空间转换函数:vctColor    

COLOR_BGR2GRAY 彩色到灰度

COLOR_GRAY2BGR 灰度到彩色

COLOR_BGR2HSV  BGR到HSV

COLOR_HSV2BGR  HSV到BGR

eg: cvtColor(image, hsv, COLOR_BGR2HSV);
   cvtColor(image, gray, COLOR_BGR2GRAY);

eg:
#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;
int main(int argc, char*** argv) {
	Mat src = imread("D://RM//练习//图像色彩转换//11.jpg");
	if (src.empty()) {
		printf("can't load image\n");
		return -1;
	}
//	namedWindow("输入窗口",WINDOW_FREERATIO);
	imshow("原图",src);
	Mat gray, hsv;
	cvtColor(src, hsv, COLOR_BGR2HSV);
	cvtColor(src, gray, COLOR_BGR2GRAY);
	imshow("HSV", hsv);
	imshow("GRAY", gray);

	imwrite("D://RM//练习//图像色彩转换//11.jpg", hsv);
	imwrite("D://RM//练习//图像色彩转换//11.jpg", gray);
	waitKey(0);
	destroyAllWindows();
}

3、阈值处理

什么是阈值处理?(0是黑,255是白)

阈值又叫临界值,是指一个效应能够产生的最低值或最高值。通俗的来,阈值是一个转换临界点,不管你的图片是什么样色彩,它最终都会把图片当黑白图片处理,也就是说你设定了一个阈值之后,它会以此值作为标准,凡是比该值大的颜色就会转换成白色,低于该值的颜色就转换成黑色,所以最后的结果是,你得到一张黑白的图片。阈值处理最终会得到一张黑白的图像。

只会固定阈值操(自适应目前还不太懂.)

函数原型:double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type) ;

参数简介:第一个参数:InputArray 类型的src,输入数组,填单通道,8或32位浮点类型的Mat. 

第二个参数:Output Array类型的dst,函数调用后的运算结果存在这里,也就是说放输出结果,与第一个参数中的Mat变量尺寸和类型相同。

第三个参数:阈值的具体值。

第四个参数:当第五个参数阈值类型type取CV_THRESH_BINARY或CV_THRESH_BINARY_INV时阈值类型的最大值。

第五个参数:int类型的type,阈值的类型。阈值类型的选取如下表所示。

代码一:
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;    
int g_nThresholdValue = 100;
int g_nThresholdType = 3;
Mat g_srcImage, g_grayImage, g_dstImage;
void ShowHelpText();
void on_Threshold(int, void*);
int main()
{
	system("color 1F");//修改控制台的颜色信息,改为白字蓝底的模式
	ShowHelpText();
	g_srcImage = imread("D:/RM/练习/阈值处理/55.jpg");
	if (!g_srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
	imshow("原始图", g_srcImage);
	cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
	namedWindow("程序窗口",WINDOW_AUTOSIZE);
	createTrackbar("模式","程序窗口", &g_nThresholdType,4, on_Threshold);
	createTrackbar("参数值","程序窗口", &g_nThresholdValue,255, on_Threshold);
	on_Threshold(0, 0);
	while (1)
	{
		int key;
		key = waitKey(20);
		if ((char)key == 27) { break; }
	}
}
void on_Threshold(int, void*)
{
	threshold(g_grayImage, g_dstImage, g_nThresholdValue, 255, g_nThresholdType);
	imshow("程序窗口", g_dstImage);
}
void ShowHelpText()
{
	printf("\n\n  ----------------------------------------------------------------------------\n");
	printf("\n\t按键操作说明: \n\n"
		"\t\t键盘按键【ESC】- 退出程序\n"
		"\t\t滚动条模式0- 二进制阈值\n"
		"\t\t滚动条模式1- 反二进制阈值\n"
		"\t\t滚动条模式2- 截断阈值\n"
		"\t\t滚动条模式3- 反阈值化为0\n"
		"\t\t滚动条模式4- 阈值化为0\n");
}
代码二:
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int g_nThresholdValue = 100;
int g_nThresholdType = 3;
Mat src, gray, dst;
void on_Threshold(int, void*);
int main() {
	system("color 1F");
	printf("\n\t按键操作说明: \n\n"
		"\t\t键盘按键【ESC】- 退出程序\n"
		"\t\t滚动条模式0- 二进制阈值\n"
		"\t\t滚动条模式1- 反二进制阈值\n"
		"\t\t滚动条模式2- 截断阈值\n"
		"\t\t滚动条模式3- 反阈值化为0\n"
		"\t\t滚动条模式4- 阈值化为0\n");
	src = imread("D:/RM/OpenCv的学习/阈值处理/55.jpg");
	if (src.empty()) {
		cout << "can not read it right..." << endl;
		return 0;
	}
	while (1) {
		imshow("原始图", src);
		cvtColor(src, gray, COLOR_BGR2GRAY);
		namedWindow("程序窗口", WINDOW_AUTOSIZE);
		createTrackbar("模式", "程序窗口", &g_nThresholdType, 4, 0);
		createTrackbar("参数值", "程序窗口", &g_nThresholdValue, 255, 0);
		on_Threshold(0, 0);

		waitKey(20);
	}
	return 0;
}

void on_Threshold(int, void*)
{
	threshold(gray, dst, g_nThresholdValue, 255, g_nThresholdType);
	imshow("程序窗口", dst);
}

其中:

(一)namedWindow()的功能就是新建一个显示窗口。可以指定窗口的类型。

原型:void nameWindow(const string& winname,int flags = WINDOW_AUTOSIZE) ;

参数1:新建的窗口的名称。自己随便取。

参数2:窗口的标识,一般默认为WINDOW_AUTOSIZE 。

WINDOW_AUTOSIZE 窗口大小自动适应图片大小,并且不可手动更改。(上面图1就是使用的它)

WINDOW_NORMAL 用户可以改变这个窗口大小(上面图2就是使用的它)
 

(二)createTrackbar是Opencv中的API,其可在显示图像的窗口中快速创建一个滑动控件,用于手动调节阈值(它的作用是生成最后的滚动条)。具体定义如下:

CV_EXPORTS int createTrackbar(const string& trackbarname, const string& winname,
                              int* value, int count,
                              TrackbarCallback onChange = 0,
                              void* userdata = 0);

参数1、trackbarname:滑动空间的名称;

参数2、winname:滑动空间用于依附的图像窗口的名称;

参数3、value:初始化阈值;

参数4、count:滑动控件的刻度范围;

参数5、TrackbarCallback是回调函数.
 

4、颜色通道 

split  通道分类 -merge  通道合并

split(): void split(InputArray m, OutputArrayOfArrays mv)
//split(image, mv);          //(输入图片,mat对象)
 

merge(InputArrayOfArrays mv, OutputArray dst) //merge(对象名channels,通道合并后的矩阵) //merge(mv, dst); //(这块为mat对象,输出图片); 

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
	Mat src = imread("D://RM//练习//颜色通道//55.jpg");
	if (src.empty()) {
		printf("can not load this image....\n");
		return -1;
	}
	imshow("输入窗口",src);
	vector<Mat>mv;
	split(src, mv);
	imshow("蓝色", mv[0]);
	imshow("绿色", mv[1]);
	imshow("红色", mv[2]);

	Mat dst;
	mv[1] = 0;
	mv[2] = 0;
	merge(mv, dst);
	imshow("蓝色", dst);
	waitKey(0);
}
这是输出蓝色的绿色和红色的同理

通道交换:

mixChannels(输入矩阵(可以1个,可以多个),矩阵个数,输出矩阵,矩阵个数,矩阵对应规则,fromTo的数组元素个数除以2)
//mixChannels(&image, 1, &dst, 1, from_to,3);
//输入的矩阵(或矩阵数组)的某些通道拆分复制给对应的输出矩阵(或矩阵数组)的某些通道中,
//其中的对应关系就由fromTo参数制定
通道交换规则int from_to[] = { 0,1,1,2,2,0 }; //即从0到1,1到2,2到0

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
	Mat src = imread("D://RM//OpenCv的学习//颜色通道//55.jpg");
	
	if (src.empty()) {
		printf("can not load this image....\n");
		return -1;
	}

	imshow("输入窗口", src);
	Mat dst;
	src.copyTo(dst);
	vector<Mat>mv;
	split(src, mv);
	imshow("蓝色", mv[0]);
	imshow("绿色", mv[1]);
	imshow("红色", mv[2]);
	int from_to[] = { 0,1,1,2,2,0 };
	mixChannels(&src, 1, &dst, 1, from_to, 3);
	imshow("通道混合", dst);
	waitKey(0);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值