1. 程式人生 > >opencv_tutorial_code學習——seamless cloning無縫融合、區域性顏色變換、去高光鏡面反射、平滑紋理

opencv_tutorial_code學習——seamless cloning無縫融合、區域性顏色變換、去高光鏡面反射、平滑紋理

From tutorial_code\photo\seamless_cloning\cloning_demo.cpp

該程式實現六種變換,分別是Normal Cloning(普通融合)、Mixed Cloning(混合融合)、Monochrome Transfer(單色畫變換)、Local Color Change(區域性顏色改變)、Local IlluminationChange(區域性亮度改變)、Texture Flattening(紋理平整)。

準備源影象如下:

 

分別是destination1.png 和source1.png,先對source1.png 進行處理,製作mask.png。

製作方法:

[1]灰度化source1.png

[2]利用畫圖工具在灰度圖上用紅線畫出目標的大致輪廓,得到圖A。

圖A如下:

 

[3]新建與圖A尺寸相同的圖B,所有畫素Scalar(0),遍歷圖A,遇到畫素為紅色,則圖B在該畫素點位置同列該點行位置以下,所有畫素值置為Scalar(255).

程式碼如下:

#include <opencv2\opencv.hpp>

using namespace cv;
using namespace std;
int main()
{
	Mat I = imread("gray.jpg");
	Mat mask(I.size(), I.type(),Scalar(0));
	int cB, cG, cR;
	for (int row = 0;row < I.rows;row++)
	{
		for (int col = 0;col < I.cols;col++)
		{
			cB = I.at<Vec3b>(row, col)[0];
			cG = I.at<Vec3b>(row, col)[1];
			cR = I.at<Vec3b>(row, col)[2];
			if ((cB < 200) && (cG < 200) && (cR > 200))
			{
				for (int i = row;i < I.rows;i++)
				{
					mask.at<Vec3b>(i, col)[0] = 255;
					mask.at<Vec3b>(i, col)[1] = 255;
					mask.at<Vec3b>(i, col)[2] = 255;
				}
			}
		}
	}

	
	imshow("mask", mask);
	imwrite("mask.jpg", mask);
	
	waitKey(0);
	return 0;

得到模板如下:


然後開始做cloning_Demo.cpp裡的六種變換:

1)  seamlessClone(src,dest, mask, p, result, 1)函式:

引數分別是源圖、目標圖、mask圖,src在dest的位置點,結果圖,融合方式。

其中mask圖中白色部分最小包圍矩形的中心點對應位置是dest的p點。

融合方式有三種,對應的數字分別是:

1NORMAL_CLONE:常用的方法,符合大多數影象融合的需求。

2MIXED_CLONE:可能導致不可期望的融合效果,不建議使用。

3FEATURE_EXCHANGE:將src完全融入dst中,基本不保留src的顏色細節

進行三種方式的融合,結果如下:



4)colorChange(source, mask, result, 1.5, .5, .5)函式:

改變圖片的顏色。

引數分別是源圖、mask圖、結果圖、R通道乘數、G通道乘數、B通道乘數,乘數範圍在0.5-2.5之間。

結果圖如下:


5)illuminationChange(source, mask, result, 0.2f, 0.4f)函式:

改變圖片亮度,去高光或鏡面反射。

引數分別是源圖、mask圖、結果圖、乘數,乘數範圍在0-2之間,0比較清晰,2比較模糊。

結果圖如下:


6)textureFlattening(source, mask, result, 30, 45, 3)函式:

平滑目標區域。

引數分別是源圖、mask圖、結果圖、低閾值、高閾值、sobel kernel核。

結果圖如下:


cloning_gui.cpp將融合演算法結合GUI互動來使用,需要寫GUI互動程式時可以參考。