OpenCV 分离颜色通道 图像混合 亮度对比度调整

OpenCV 分离颜色通道 图像混合 亮度对比度调整

概述

  1. 读取两张图片,将一张图片插入另一张图片进行混合
  2. 将图片1的颜色通道分离
  3. 分别将图片2插入图片1的蓝色和红色通道进行混合
  4. 合并颜色通道
  5. 调整合并后图像的亮度和对比度
    懒,图片素材直接取自浅墨的图片。

代码段

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace std;
using namespace cv;
/*窗口相关变量*/
#define WinName "showImage"
int lightness = 80;
int contrast = 80;
void on_trackbar(int, void*);
bool createWin();
/*通道混合相关变量*/
vector<Mat> g_MatCh;
Mat g_imageBlueCh;
Mat g_imageGreenCh;
Mat g_imageRedCh;

Mat g_srcImage, g_dstImage,g_mask;
Mat imageROI;
bool main()
{
    g_srcImage = imread("dota_pa.jpg");
    /*第二个参数很重要 这里将图片以灰度图方式传入 这样在后面加权平均时才不会发生内存溢出*/
    g_mask = imread("dota_logo.jpg",0);
    if (!g_srcImage.data) { cout << "srcImage load failure" << endl; return false; }//判断图像是否成功载入
    if (!g_mask.data) { cout << "mask load failure" << endl; return false; }

    split(g_srcImage, g_MatCh); //分离各通道
    g_imageBlueCh  = g_MatCh.at(0);
    g_imageGreenCh = g_MatCh.at(1);
    g_imageRedCh   = g_MatCh.at(2);

    createWin();//创建窗口
    //回调函数初始化
    on_trackbar(lightness, 0); 
    on_trackbar(contrast, 0); 
    waitKey(0);
}
/*创建窗口和trackbar*/
bool createWin()
{
    namedWindow(WinName);
    createTrackbar("lightness", WinName, &lightness, 200, on_trackbar);
    createTrackbar("contrast", WinName, &contrast, 300, on_trackbar);
    return true;
}
/*TrackBar 回调函数*/
void on_trackbar(int, void*)
{
    imageROI = g_imageBlueCh(Rect(200, 250, g_mask.cols, g_mask.rows)); //在蓝色通道划定感兴趣区域
    addWeighted(imageROI, 0.5, g_mask, 0.5, 0.0,
        imageROI);
    imshow("蓝色通道叠加后", g_imageBlueCh);

    imageROI = g_imageRedCh(Rect(200, 250, g_mask.cols, g_mask.rows)); //在红色通道划定感兴趣区域
    addWeighted(imageROI, 0.5, g_mask, 0.5, 0.0,
        imageROI);
    imshow("红色通道叠加后", g_imageRedCh);

    merge(g_MatCh, g_dstImage); //合并各通道
    /*亮度对比度调整*/
    for(int y=0;y<g_dstImage.rows;y++)
        for(int x=0;x<g_dstImage.cols;x++)
            for (int c = 0; c < 3; c++)
            {
                g_dstImage.at<Vec3b>(y, x)[c] = 
                    saturate_cast<uchar>(((contrast*0.01)*g_dstImage.at<Vec3b>(y, x)[c]) + lightness);
            }
    imshow(WinName, g_dstImage);
}

程序运行效果

蓝色通道叠加logo后的效果
图1 蓝色通道叠加后的效果

红色通道叠加后的效果
图2 红色通道叠加后的效果
最终效果
图3 合并通道后的效果

效果分析

在一张图中一个像素的色彩组成可以从通道分离后看出。例如 *图1 蓝色通道* 在原图中蓝色约深的地方,在图1 中表现的更明亮,反之,则更暗。分别将logo混合进蓝色通道和红色通道后 ,再将各通道合并,将得到紫色的logo。 在亮度和对比度调整时,要对每一个像素的每一个通道进行调整。一般遍历图象是2重循环,这里出现了三重循环,最里面一层则是分别访问每个像素的B、G、R通道。 这种点操作(亮度调整和对比度调整)的理论公式为:
                               g(i,j)=a*f(i,j)+b
其中a称为增益(gain),常用来控制对比度。b称为偏置(bias),常用来控制亮度。f(i,j)为图像中每个像素。g(i,j)为计算后的像素值。

注意事项

在这个程序中容易出现的几种问题:
  1. 单通道图像不能和多通道图像混合,否则将内存溢出。g_mask = imread("dota_logo.jpg",0); 第二个参数意义为将图片以灰度图读入,在后面的与单通道图像混合时才不至于引发错误。
  2. addWeighted(imageROI, 0.5, g_mask, 0.5, 0.0,imageROI); 最后一个参数为ROI,为原图像的引用,因此将加权叠加后的图像输出到ROI即改变了原图像对应的区域。
  3. 在调整图像时为了避免像素值溢出需要加上saturate_cast<uchar>

心得

图像较大时,遍历处理每一个像素将会对程序性能造成很大影响,因此在编写图像处理程序时还得考虑如何提高效率。加油。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在C++中,可以使用OpenCV库来实现图像亮度对比度和伽马值调整。下面是一个简单的示例代码: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; // 亮度对比度调整函数 void adjustBrightnessContrast(Mat& image, double alpha, int beta) { // 遍历图像的每个像素 for (int y = 0; y < image.rows; y++) { for (int x = 0; x < image.cols; x++) { for (int c = 0; c < image.channels(); c++) { // 对每个通道的像素进行亮度对比度调整 image.at<Vec3b>(y, x)[c] = saturate_cast<uchar>(alpha * image.at<Vec3b>(y, x)[c] + beta); } } } } // 伽马值调整函数 void adjustGamma(Mat& image, double gamma) { // 建立查找表 unsigned char lut[256]; for (int i = 0; i < 256; i++) { lut[i] = saturate_cast<uchar>(pow((double)i / 255.0, gamma) * 255.0); } // 应用查找表 image = image.clone(); LUT(image, Mat(1, 256, CV_8UC1, lut), image); } int main() { // 读取图像 Mat image = imread("input.jpg"); if (image.empty()) { std::cerr << "Failed to read image." << std::endl; return -1; } // 调整亮度对比度 double alpha = 1.5; // 亮度调整参数 int beta = 30; // 对比度调整参数 adjustBrightnessContrast(image, alpha, beta); // 调整伽马值 double gamma = 1.5; // 伽马值调整参数 adjustGamma(image, gamma); // 显示结果图像 imshow("Adjusted Image", image); waitKey(0); return 0; } ``` 在这个示例代码中,我们首先定义了两个函数:`adjustBrightnessContrast`和`adjustGamma`,分别用于亮度对比度、伽马值的调整。然后在`main`函数中,我们读取了一张图像,然后分别调用这两个函数进行图像处理。最后,将处理后的图像显示出来。 请确保在编译和运行代码之前,已经安装了OpenCV库,并将示例代码中的`input.jpg`替换为你自己的图像路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liangtao`

请作者喝杯咖啡吧~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值