1. 程式人生 > >OpenCV簡單實現PhotoShop圖層混合

OpenCV簡單實現PhotoShop圖層混合

暫時不知道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;
}