Mix Channels 將影像的 R、G、B 三個通道線性重組,產生新的色彩映射。每個輸出通道為輸入通道的加權組合,可實現色調偏移、通道交換、單色化等效果。
CV_32FC3 浮點格式(0~1 正規化),便於線性運算。split 分離三通道:b, g, r。blueGreen:藍綠混合比例(輸出紅通道參考)redBlue:紅藍混合比例(輸出綠通道參考)greenRed:綠紅混合比例(輸出藍通道參考)intoR, intoG, intoB:原通道保留比例。N_R = intoR * (blueGreen*g + (1-blueGreen)*b) + (1-intoR)*rN_G = intoG * (redBlue*b + (1-redBlue)*r) + (1-intoG)*gN_B = intoB * (greenRed*r + (1-greenRed)*g) + (1-intoB)*bmerge 合併三通道,除以 255 歸一化顯示。#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 | 均衡混合,類似色盲模擬 |
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 以矩陣乘法實現通道線性組合,效能更高且數學表達更清晰。