1. 程式人生 > >python opencv 將一張圖片無縫合成到另一張圖片中

python opencv 將一張圖片無縫合成到另一張圖片中

原文地址:Seamless Cloning using OpenCV (Python , C++)

無縫合成(Seamless Cloning)是 opencv3 的新特性。

利用這個新特性,我們可以從一個影象複製物件,並將其貼上到另一個影象中,同時使組合看起來無縫和自然。

比如說下面這個圖就是飛機和天空無縫合成的結果
opencv-seamless-cloning-example
想要達到上述效果,我們主要的函式就是 cv2.seamlessClone,其定義如下:

output = cv2.seamlessClone(src, dst, mask, center, flags)
引數 含義
src Source image that will be cloned into the destination image. In our example it is the airplane.
dst Destination image into which the source image will be cloned. In our example it is the sky image.
mask A rough mask around the object you want to clone. This should be the size of the source image. Set it to an all white image if you are lazy!
center Location of the center of the source image in the destination image.
flags The two flags that currently work are NORMAL_CLONE and MIXED_CLONE. I have included an example to show the difference.
output Output / result image.

實現上述效果的程式碼如下:

# Standard imports
import cv2
import numpy as np 

# Read images
src = cv2.imread("images/airplane.jpg")
dst = cv2.imread("images/sky.jpg")

# Create a rough mask around the airplane.
src_mask = np.zeros(src.shape, src.dtype)

# 當然我們比較懶得話,就不需要下面兩行,只是效果差一點。
# 不使用的話我們得將上面一行改為 mask = 255 * np.ones(obj.shape, obj.dtype) <-- 全白
poly = np.array([ [4,80], [30,54], [151,63], [254,37], [298,90], [272,134], [43,122] ], np.int32)
cv2.fillPoly(src_mask, [poly], (255, 255, 255))

# 這是 飛機 CENTER 所在的地方
center = (800,100)

# Clone seamlessly.
output = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE)

# 儲存結果
cv2.imwrite("images/opencv-seamless-cloning-example.jpg", output);

飛機和天空的圖片可以在下面兩個網址找到。
sky
plane

值得一提的是,那個 poly 引數應該是經過仔細計算的。因為一開始我沒看到圖源,就自己修了下圖,結果產生下面的錯誤:

Traceback (most recent call last):
  File "C:\Users\Administrator\Desktop\test3.py", line 19, in <module>
    output = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE)
cv2.error: OpenCV(3.4.3) C:\projects\opencv-python\opencv\modules\core\src\matrix.cpp:465: error: (-215:Assertion failed) 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows in function 'cv::Mat::Mat'

更多內容請看原文,我這裡只舉了其中的一個例子。