您好,登錄后才能下訂單哦!
Python+OpenCV如何實現自動海報場景替換,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
現存在一個問題,就下面圖片中的兩本書而言,怎樣快速讓中間邊的書本與左邊書本對齊(最終效果能實現兩張圖片重疊(最終結果為右圖)),進行的圖像轉變可旋轉、平移、縮放、形變。
主要內容就是介紹利用 Opencv 來怎樣解決上面的問題,解決這個問題需要三步
確定至少四組對應點坐標
找到一個轉換矩陣;
把找到的轉換矩陣應用到 Moving Image(需要移動的圖片) 上,實現圖像對齊
圖片旋轉、平移、縮放等操作的主要目的,就是要最終實現兩圖像中點對點一一映射關系,圖像映射本質上就是像素點轉換
圖中標記了其中四組對應點,分別標為不同的顏色,分別標為紅、橙、黃和綠四種顏色;比如這里的 和 是就是一組對應點,圖片經過轉換之后 點 必須映射到 點位置。
涉及圖片中點坐標變換,都需要借助于 矩陣 運算,這里探究的圖像維度都屬于二維,坐標只需要 即可
面向此類轉換問題,Homography 轉換 ( 3 × 3 矩陣) 可用于解決此類轉化問題,用來解決點對點映射問題,Homography 矩陣可寫作下列方式:
則 、 作為對應點,則 Homography 的的應用 如下:
而矩陣 H 參數的確定至少需要 4 組對應點,因此在計算 H 時至少要找到 4 組對應點;找到的對應點組數越多,計算得到的 H 會越精確,最終的轉換效果也就會越好。
下面用 Opencv + Python 來實現上面圖片中的書籍的對齊,
import cv2
import numpy as np
if __name__ =='__main__':
#圖片讀取
img_src = cv2.imread("D:/book2.jpg")
position_src = np.array([[141,131],[480,159],[493,630],[64,601]],dtype = float)
img_dst = cv2.imread("D:/book1.jpg")
position_dst = np.array([[318,256],[543,372],[316,670],[73,473]],dtype = float)
#計算轉換矩陣
h,status = cv2.findHomography(position_src,position_dst)
#對圖片進行仿射變換
out_img = cv2.warpPerspective(img_src,h,(img_dst.shape[1],img_dst.shape[0]))
#Display images;
cv2.imshow("Source image",img_src)
cv2.imshow("Destination Image",img_dst)
cv2.imshow("Warped Source Image",out_img)
cv2.waitKey(0)
這里事先已經確定好對應的四個點的坐標,然后把這四個點的坐標帶入 cv2.findHomography() 計算出轉換矩陣,最后把矩陣應用到兩圖像中,得到最終的轉換結果,
這里提醒一點,warpPerspective 函數進行對圖像像素進行矩陣變換時,隱藏了一個參數 Interpolator ,默認為線性插值,功能是防止像素點像素值缺失
上面小案例不方便的一點需要確定對應四個點的坐標,這個步驟是比較繁瑣的,下面案例將在程序中加入交互功能,實現某個圖片的自動標記點收集、標記點點轉換:
首先需要準備兩張圖片,其中一張為海報,一張為需要替換的海報;關于確定點的坐標時,被替換的圖片的坐標非常好確定,只需知道圖片的長寬即可;
但的海報圖像區域四個點是不好確定的, 這里利用 Opencv 的鼠標回調函數,監視鼠標響應,根據用戶點擊來收集 PIck 得到的坐標;
def mouse_handler(event,x,y,flags,data):
if event ==cv2.EVENT_LBUTTONDOWN:
cv2.circle(data['im'],(x,y),3,(0,0,255),5,16)
cv2.namedWindow("Image",0)
cv2.imshow("Image",data['im'])
if len(data['points']) <4:
data['points'].append([x,y])
def get_four_points(im):
data = {}
data['im'] = im.copy()
data['points'] = []
# Set the callback function for any mouse event
cv2.namedWindow("Image", 0)
cv2.imshow('Image',im)
#請注意你標記點的數據,是順時針,需要與pst_src 方向一致
cv2.setMouseCallback("Image",mouse_handler,data)
cv2.waitKey(0)
# Convert array to np.array
#豎直方向堆疊起來;;;
points = np.vstack(data['points']).astype(float)
return points
坐標確定以后,接下來就很簡單了,跟上個案例一樣,計算變換矩陣,矩陣應用到圖像旋轉,最終更換海報內容也就輕松完成啦
需要注意一點,坐標 Pick 點的順序須與記錄替換圖像頂點順序一致,否則轉換圖會有偏差,案例完整代碼如下:
if __name__ =='__main__':
img_src = cv2.imread("D:/first-image.jpg")
size = img_src.shape
# 取得四個坐標
pst_src = np.array(
[
[0,0],[size[1]-1,0],
[size[1]-1,size[0]-1],
[0,size[0]-1]
],dtype=float
)
#Read the destination image
img_dst = cv2.imread("D:/times-square.jpg")
print("Click on four corners of bllboard and the press ENTER")
four_point = get_four_points(img_dst)
# Calculate Homography between source and destination points
h,status = cv2.findHomography(pst_src,four_point)
im_temp = cv2.warpPerspective(img_src,h,(img_dst.shape[1],img_dst.shape[0]))
cv2.fillConvexPoly(img_dst,four_point.astype(int),0,16)
#add wraped source image to destination image
img_dst = img_dst + im_temp
cv2.namedWindow("Image", 0)
cv2.imshow("Image",img_dst)
cv2.waitKey(0)
看完上述內容,你們掌握Python+OpenCV如何實現自動海報場景替換的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。