python opencv 將一張圖片無縫合成到另一張圖片中
阿新 • • 發佈:2018-12-21
原文地址:Seamless Cloning using OpenCV (Python , C++)
無縫合成(Seamless Cloning)是 opencv3 的新特性。
利用這個新特性,我們可以從一個影象複製物件,並將其貼上到另一個影象中,同時使組合看起來無縫和自然。
比如說下面這個圖就是飛機和天空無縫合成的結果
想要達到上述效果,我們主要的函式就是 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'
更多內容請看原文,我這裡只舉了其中的一個例子。