簡體   English   中英

Python,OpenCV 查找和覆蓋/替換圖像的部分

[英]Python, OpenCV to find and overlay/replace portions of an image

需要找到並用其他圖像替換圖像中的某些部分。

原始圖像如下所示。 我想查找和替換:

blue squares to blue triangles
orange squares to orange octagons

在此處輸入圖片說明

圖像文件如下:

original.jpg, blue square.jpg, orange square.jpg, blue triangle.jpg, orange octagon.jpg

在此處輸入圖片說明 在此處輸入圖片說明 在此處輸入圖片說明 在此處輸入圖片說明

使用 cv2,我可以找到目標圖像的位置。

import cv2
import numpy as np

img_original = cv2.imread("C:\\original.jpg")

img_to_replace_0 = cv2.imread("C:\\blue square.jpg")
img_to_replace_1 = cv2.imread("C:\\orange square.jpg")

img_overlay_0 = cv2.imread("C:\\blue triangle.jpg")
img_overlay_1 = cv2.imread("C:\\orange octagon.jpg")

res_0 = cv2.matchTemplate(img_original, img_to_replace_0, cv2.TM_CCOEFF_NORMED)
res_1 = cv2.matchTemplate(img_original, img_to_replace_1, cv2.TM_CCOEFF_NORMED)

threshold = 0.80
loc_0 = np.where (res_0 >= threshold)
loc_1 = np.where (res_1 >= threshold)

bl_0 = list(loc_0)
bl_1 = list(loc_1)

print bl_0
print bl_1

輸出是:

[array([106, 294, 477]), array([17, 18, 21])]
[array([ 22, 210, 393]), array([16, 17, 20])]

進一步進行的最佳方法是什么? CV2 是這種情況下的最佳工具嗎? 謝謝你。

是的,可以從這一點繼續。 您將獲得每個的位置,第一個數組是y軸,第二個數組是x軸。 該位置是對象的左上角。

這里可能存在的問題是模板具有不同的大小......所以它可能與原始圖像中沒有發生的圖像的其他部分重疊,我不知道這是否是一個問題。 因此,如果這是一個問題,您可能必須確保所有這些都同樣大或它們有足夠的空間。 這可以解決,例如將圖像縮放為相同大小。

無論如何,您可以像這樣實現替換:

import cv2
import numpy as np

# load the data
img = cv2.imread('scene.jpg')
blueTri = cv2.imread('blueTri.jpg')
blueSq = cv2.imread('blueSq.jpg')
bgColor = (255,255,255)

# find the matching rectangles
res = cv2.matchTemplate(img, blueSq, cv2.TM_CCOEFF_NORMED)
threshold = 0.98 # I used a higher threshold, because it was giving several "good" locations that are next to each other
loc = np.where (res >= threshold)

# process the positions
for i in range(len(loc[0])):
  # it is given as (y,x)
  pos = (loc[0][i], loc[1][i])
  # delete the blue squares
  img[pos[0]:pos[0]+blueSq.shape[0] , pos[1]:pos[1]+blueSq.shape[1] ] = bgColor
  # put the new blue triangle
  img[pos[0]:pos[0]+blueTri.shape[0] , pos[1]:pos[1]+blueTri.shape[1] ] = blueTri


cv2.imshow("Frame", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

這是藍色方塊到藍色三角形的結果:

在此處輸入圖片說明

對於您的示例中的兩個更改:

在此處輸入圖片說明

如果兩個模板的大小相等(即您要查找的圖像和將要替換的圖像),您可以減少一步並將 for 循環更改為:

# process the positions
for i in range(len(loc[0])):
  # it is given as (y,x)
  pos = (loc[0][i], loc[1][i])
  # put the new blue triangle
  img[pos[0]:pos[0]+blueTri.shape[0] , pos[1]:pos[1]+blueTri.shape[1] ] = blueTri

更新

要移動您正在復制的形狀,您可以移動整個 ROI,無論如何您已經刪除了舊的,這樣就可以了。 只是不要忘記檢查圖像的限制。 為此,您可以執行以下操作:

for i in range(len(loc[0])):
  posToDelete = (loc[0][i], loc[1][i])
  posToAdd = (loc[0][i] -10, loc[1][i]+15) # 10 pixels up and 15 to the right
  posToAdd = (max(0, min(posToAdd[0],img.shape[0]-1 -blueTri.shape[0] )) , max(0, min(posToAdd[1],img.shape[1]-1-blueTri.shape[1]))) # sanity check to make sure it is inside the borders
  img[posToDelete[0]:posToDelete[0]+blueSq.shape[0] , posToDelete[1]:posToDelete[1]+blueSq.shape[1] ] = bgColor
  img[posToAdd[0]:posToAdd[0]+blueTri.shape[0] , posToAdd[1]:posToAdd[1]+blueTri.shape[1] ] = blueTri

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM