首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

OpenCV 通道操作:Mix Channels(色彩通道混合重組)實現

     編輯:關於C++

效果描述

Mix Channels 將影像的 R、G、B 三個通道線性重組,產生新的色彩映射。每個輸出通道為輸入通道的加權組合,可實現色調偏移、通道交換、單色化等效果。

核心演算法

  1. 將輸入影像轉為 CV_32FC3 浮點格式(0~1 正規化),便於線性運算。
  2. split 分離三通道:b, g, r。
  3. 定義混合權重:
    blueGreen:藍綠混合比例(輸出紅通道參考)
    redBlue:紅藍混合比例(輸出綠通道參考)
    greenRed:綠紅混合比例(輸出藍通道參考)
    intoR, intoG, intoB:原通道保留比例。
  4. 計算新通道:
    N_R = intoR * (blueGreen*g + (1-blueGreen)*b) + (1-intoR)*r
    N_G = intoG * (redBlue*b + (1-redBlue)*r) + (1-intoG)*g
    N_B = intoB * (greenRed*r + (1-greenRed)*g) + (1-intoB)*b
  5. merge 合併三通道,除以 255 歸一化顯示。

完整 OpenCV C++ 實現

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

void showImage(const Mat& img, const string& name) {
    namedWindow(name, WINDOW_AUTOSIZE);
    imshow(name, img);
}

int main() {
    Mat src = imread("4.jpg");
    if (src.empty()) return -1;

    Mat src32f;
    src.convertTo(src32f, CV_32FC3, 1.0/255.0); // 正規化到 [0,1]

    vector<Mat> channels;
    split(src32f, channels);
    Mat b = channels[0], g = channels[1], r = channels[2];

    float blueGreen = 0.5f, redBlue = 0.5f, greenRed = 0.5f;
    float intoR = 0.75f, intoG = 0.25f, intoB = 0.75f;

    Mat nR = intoR * (blueGreen * g + (1-blueGreen) * b) + (1-intoR) * r;
    Mat nG = intoG * (redBlue * b + (1-redBlue) * r) + (1-intoG) * g;
    Mat nB = intoB * (greenRed * r + (1-greenRed) * g) + (1-intoB) * b;

    vector<Mat> outChannels = {nB, nG, nR}; // BGR 順序
    Mat dst;
    merge(outChannels, dst);

    showImage(dst, "Channel Mix");
    waitKey(0);
    return 0;
}

參數效果範例

參數組合視覺效果
blueGreen=redBlue=greenRed=0, intoR=intoG=intoB=1原圖(無變化)
intoR=intoG=intoB=0完全交叉混合,色調劇烈偏移
blueGreen=1, redBlue=1, greenRed=1循環移位:R←G, G←B, B←R
intoR=intoG=intoB=0.5均衡混合,類似色盲模擬

OpenCV 內建替代:mixChannels / transform


// mixChannels: 任意通道複製/重排
Mat dst(src.size(), src.type());
int fromTo[] = {0,2, 1,1, 2,0}; // B→R, G→G, R→B (交換 R/B)
mixChannels(&src, 1, &dst, 1, fromTo, 3);

// transform: 3x3/3x4 矩陣線性變換(含平移)
Matx33f M(0,1,0, 0,0,1, 1,0,0); // 循環移位
transform(src, dst, M);

transform 以矩陣乘法實現通道線性組合,效能更高且數學表達更清晰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved