OpenCV学习笔记 core库6.对图像通道、对比度和亮度的操作

颜色通道的分离与合并

分离颜色通道 split()
函数原型
//该函数有两个原型
void split(const Mat& src, Mat *mvbegin);
void split(InputArray m, OutputArrayOfArrays mv);

第一个参数是我们需要进行分离的多通道数组
第二个参数是函数的输出数组或输出的vector容器

示例程序
vector<Mat> channels;
Mat imgBluChannel;
Mat imgGreChannel;
Mat imgRedChannel;

Mat srcImg = imread("Test.jpg");	//三通道图像
split(srcImg, channels);			//分离
//OpenCV的BGR色彩空间
imgBluChannel = channels.at(0);
imgGreChannel = channels.at(1);
imgRedChannel = channels.at(2);

channels.at(0)表示引用取出channels中的蓝色分量,其余两个同理
关于.at
opencv中Mat格式的数据访问.at

分离后为单通道,相当于分离通道的同时把其他两个通道填充了相同的数值。比如红色通道,分离出红色通道的同时,绿色和蓝色被填充为和红色相同的数值,这样一来就只有黑白灰了。

通道合并 merge()
函数原型
void merge(const Mat* mv, size_t count, OutputArray dst);
void merge(InputArrayOfArrays mv, OutputArray dst);

第一个参数填需要被合并的输入矩阵或vector容器的阵列,所有矩阵需要有一样的尺寸和深度
第二个参数count代表输入矩阵的个数
第三个参数为输出矩阵,尺寸和深度与输入矩阵相同,通道数是输入矩阵的通道总数

关于size_t,引自https://blog.csdn.net/qq_41598072/article/details/84924997
在32位架构中被普遍定义为:
typedef unsigned int size_t;
而在64位架构中被定义为:
typedef unsigned long size_t;
int为带符号数,size_t为无符号数

示例程序

图像对比度、亮度值

原理

g ( i , j ) = a ∗ f ( i , j ) + b g(i,j)=a*f(i,j)+b g(i,j)=af(i,j)+b
f(i,j)是源图像像素
a(a>0)为增益(gain),用来控制对比度
b为偏置(bias),用来控制亮度
g(i,j)为输出图像像素

访问像素
for(int y=0; y<image.rows; ++y)
{
	for(int x=0; x<image.cols; ++x)
	{
		for(int c=0; c<3; ++c)
		{
			new_image.at<Vec3b>(y,x)[c]= saturate_case<uchar>((a_contrastValue*0.01)*(image.at<Vec3b>(y,x)[c])+b_BrightValue);
		}
	}
}

示例

#include "opencv2/opencv.hpp"
#include <cstdlib>
#include <vector>

#define WIN_NAME "TEST"
#define BAR_NAME_1 "Channel Choice"
#define BAR_NAME_2 "Bright"
#define BAR_NAME_3 "Contrast"

using namespace cv;

int track_value_1;
int track_value_2 = 50;
int track_value_3 = 100;
std::vector<Mat> channels;
Mat imgSrc, imgTest;
Mat imgBlue;
Mat imgGreen;
Mat imgRed;

void onChange_1(int, void*);
void onChange_2(int, void*);

int main()
{
    imgSrc = imread("aete.jpg");
    imgTest = imgSrc.clone();
    split(imgTest, channels);

    imgBlue = channels.at(0);
    imgGreen = channels.at(1);
    imgRed = channels.at(2);

    namedWindow(WIN_NAME);
    createTrackbar(BAR_NAME_1, WIN_NAME, &track_value_1, 3, onChange_1);
    createTrackbar(BAR_NAME_2, WIN_NAME, &track_value_2, 100, onChange_2);
    createTrackbar(BAR_NAME_3, WIN_NAME, &track_value_3, 200, onChange_2);

    printf("Display mode: ALL CHANNEL");

    waitKey(0);
}
void onChange_1(int, void*)
{
    system("CLS");
    switch(track_value_1)
    {       
        case 0:
            printf("Display mode: ALL_CHANNEL");
            imshow(WIN_NAME, imgTest);
            break;
        case 1:
            printf("Display mode: BLUE_CHANNEL");
            imshow(WIN_NAME, imgBlue);
            break;
        case 2:
            printf("Display mode: GREEN_CHANNEL");
            imshow(WIN_NAME, imgGreen);
            break;
        case 3:
            printf("Display mode: RED_CHANNEL");
            imshow(WIN_NAME, imgRed);
            break;
    }
}
void onChange_2(int, void*)
{
    for(int y = 0; y < imgSrc.rows; y++ )
       {
              for(int x = 0; x < imgSrc.cols; x++ )
              {
                     for(int c = 0; c < 3; c++ )
                     {
                            imgTest.at<Vec3b>(y,x)[c]= saturate_cast<uchar>( (track_value_3*0.01)*(imgSrc.at<Vec3b>(y,x)[c] ) + track_value_2 );
                     }
              }
       }
    imshow(WIN_NAME, imgTest);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值