OpenCV簡單實現PhotoShop圖層混合
阿新 • • 發佈:2018-12-30
暫時不知道OpenCV本身有沒有更好的方法支援混合 ,於是自己簡單的實現了一下,現提供給大夥看看
#include "stdafx.h" #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <windows.h> #define ChannelBlend_Normal(A,B) ((uchar)(A)) #define ChannelBlend_Lighten(A,B) ((uchar)((B > A) ? B:A)) #define ChannelBlend_Darken(A,B) ((uchar)((B > A) ? A:B)) #define ChannelBlend_Multiply(A,B) ((uchar)((A * B) / 255)) #define ChannelBlend_Average(A,B) ((uchar)((A + B) / 2)) #define ChannelBlend_Add(A,B) ((uchar)(min(255, (A + B)))) #define ChannelBlend_Subtract(A,B) ((uchar)((A + B < 255) ? 0:(A + B - 255))) #define ChannelBlend_Difference(A,B) ((uchar)(abs(A - B))) #define ChannelBlend_Negation(A,B) ((uchar)(255 - abs(255 - A - B))) #define ChannelBlend_Screen(A,B) ((uchar)(255 - (((255 - A) * (255 - B)) >> 8))) #define ChannelBlend_Exclusion(A,B) ((uchar)(A + B - 2 * A * B / 255)) #define ChannelBlend_Overlay(A,B) ((uchar)((B < 128) ? (2 * A * B / 255):(255 - 2 * (255 - A) * (255 - B) / 255))) #define ChannelBlend_SoftLight(A,B) ((uchar)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255)))) #define ChannelBlend_HardLight(A,B) (ChannelBlend_Overlay(B,A)) #define ChannelBlend_ColorDodge(A,B) ((uchar)((B == 255) ? B:min(255, ((A << 8 ) / (255 - B))))) #define ChannelBlend_ColorBurn(A,B) ((uchar)((B == 0) ? B:max(0, (255 - ((255 - A) << 8 ) / B)))) #define ChannelBlend_LinearDodge(A,B)(ChannelBlend_Add(A,B)) #define ChannelBlend_LinearBurn(A,B) (ChannelBlend_Subtract(A,B)) #define ChannelBlend_LinearLight(A,B)((uchar)(B < 128)?ChannelBlend_LinearBurn(A,(2 * B)):ChannelBlend_LinearDodge(A,(2 * (B - 128)))) #define ChannelBlend_VividLight(A,B) ((uchar)(B < 128)?ChannelBlend_ColorBurn(A,(2 * B)):ChannelBlend_ColorDodge(A,(2 * (B - 128)))) #define ChannelBlend_PinLight(A,B) ((uchar)(B < 128)?ChannelBlend_Darken(A,(2 * B)):ChannelBlend_Lighten(A,(2 * (B - 128)))) #define ChannelBlend_HardMix(A,B) ((uchar)((ChannelBlend_VividLight(A,B) < 128) ? 0:255)) #define ChannelBlend_Reflect(A,B) ((uchar)((B == 255) ? B:min(255, (A * A / (255 - B))))) #define ChannelBlend_Glow(A,B) (ChannelBlend_Reflect(B,A)) #define ChannelBlend_Phoenix(A,B) ((uchar)(min(A,B) - max(A,B) + 255)) #define ChannelBlend_Alpha(A,B,O) ((uchar)(O * A + (1 - O) * B)) #define ChannelBlend_AlphaF(A,B,F,O) (ChannelBlend_Alpha(F(A,B),A,O)) using namespace cv; using namespace std; int blendX_ = 0; int blendY_ = 0; int blendWidth_ = 400; int blendHeight_ = 400; int _tmain(int argc, _TCHAR* argv[]) { Mat srcImg = imread("srcImg.jpg"); Mat blendImg = imread("blendImg.jpg"); Mat outputImg ; //check? if (srcImg.rows < blendX_ + blendWidth_||blendImg.rows < blendX_ + blendWidth_|| srcImg.cols < blendY_ + blendHeight_||blendImg.cols < blendY_ + blendHeight_) { exit(1); } // create vector of 3 images vector<Mat> srcImgPlanes; // split 1 3-channel image into 3 1-channel images split(srcImg,srcImgPlanes); // create vector of 3 images vector<Mat> blendImgPlanes; // split 1 3-channel image into 3 1-channel images split(blendImg,blendImgPlanes); //check plane size? for (int i=0;i<3;i++) { Mat src = srcImgPlanes[i]; Mat blend = blendImgPlanes[i]; for (int row = blendX_; row < blendX_ + blendWidth_; row++) { // get the address of row uchar* srcdata= src.ptr<uchar>(row); uchar* blenddata= blend.ptr<uchar>(row); for (int col = blendY_; col < blendY_ + blendHeight_; col++) { // process each pixel --------------------- srcdata[col] = ChannelBlend_Darken(blenddata[col],srcdata[col]); } } } merge(srcImgPlanes,outputImg); namedWindow("Image"); imshow("Image",outputImg); waitKey(50000); destroyAllWindows(); return 0; }