OpenCV 分離顏色通道 影象混合 亮度對比度調整
阿新 • • 發佈:2018-11-20
OpenCV 分離顏色通道 影象混合 亮度對比度調整
概述
- 讀取兩張圖片,將一張圖片插入另一張圖片進行混合
- 將圖片1的顏色通道分離
- 分別將圖片2插入圖片1的藍色和紅色通道進行混合
- 合併顏色通道
- 調整合並後圖像的亮度和對比度
懶,圖片素材直接取自淺墨的圖片。
程式碼段
#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);
}
程式執行效果
圖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)為計算後的畫素值。
注意事項
在這個程式中容易出現的幾種問題:- 單通道影象不能和多通道影象混合,否則將記憶體溢位。
g_mask = imread("dota_logo.jpg",0);
第二個引數意義為將圖片以灰度圖讀入,在後面的與單通道影象混合時才不至於引發錯誤。 addWeighted(imageROI, 0.5, g_mask, 0.5, 0.0,imageROI);
最後一個引數為ROI,為原影象的引用,因此將加權疊加後的影象輸出到ROI即改變了原影象對應的區域。- 在調整影象時為了避免畫素值溢位需要加上
saturate_cast<uchar>
。
心得
影象較大時,遍歷處理每一個畫素將會對程式效能造成很大影響,因此在編寫影象處理程式時還得考慮如何提高效率。加油。