【发布时间】:2020-07-25 18:02:34
【问题描述】:
我正在尝试在 Python 3.6 中配置 OpenCV,以将字符图标(模式)1 与字符框 2 匹配。尽管如此,匹配度还是很低,尤其是对于像1 这样的阴影字符。
我尝试通过不仅使用 matchTemplate,还比较直方图来解决它,但是 - 结果仍然很差。
我确实尝试过使用灰度、颜色、仅匹配图片中心(裁剪的脸)、匹配整个图片...调整图案大小以使其具有精确的尺寸,就像它在盒子中一样...所有组合.. . 但这仍然是非常随机的(参见相关结果的附图)
提前感谢您的帮助!
代码如下:
import numpy as np
import cv2 as cv
from PIL import Image
import os
box = Image.open("/Users/user/Desktop/dbz/my_box.jpeg")
box.thumbnail((592,1053))
#conditions for each match step
character_threshold = 0.6 #checks in box
hist_threshold = 0.3
import numpy as np
import cv2 as cv
from PIL import Image
import os
box = Image.open("/Users/user/Desktop/dbz/my_box.jpeg")
box.thumbnail((592,1053))
#conditions for each match step
character_threshold = 0.6
hist_threshold = 0.3
for root, dirs, files in os.walk("/Users/user/Desktop/dbz/img/Super/TEQ/"):
for file in files:
if not file.startswith("."):
print("now " + file)
char = os.path.join(root, file)
#Opens and generate character's icon
character = Image.open(char)
character.thumbnail((153,139))
#Crops face from the character's icon and converts to grayscale CV object
face = character.crop((22,22,94,94)) #size 72x72 with centered face (should be 22,22,94,94)
face_array = np.array(face).astype(np.uint8)
face_array_gray = cv.cvtColor(face_array, cv.COLOR_RGB2GRAY)
#Converts the character's icon to grayscale CV object
character_array = np.array(character).astype(np.uint8)
character_array_gray = cv.cvtColor(character_array, cv.COLOR_RGB2GRAY)
#Converts box screen to grayscale CV object
box_array = np.array(box).astype(np.uint8)
box_array_gray = cv.cvtColor(box_array, cv.COLOR_RGB2GRAY)
#Check whether the face is in the box
character_score = cv.matchTemplate(box_array[:,:,2],face_array[:,:,2],cv.TM_CCOEFF_NORMED)
if character_score.max() > character_threshold:
ij = np.unravel_index(np.argmax(character_score),character_score.shape)
x, y = ij[::-1] #np returns lower-left coordinates, whilst PIL accepts upper, left,lower, right !!!
w, h = face_array_gray.shape
face.show()
found = box.crop((x,y,x+w,y+h)) #expand border to 25 pixels in each size (Best is (x-20,y-5,x+w,y+h+20))
#found.show()
#found_character = np.array(found_character).astype(np.uint8)
#found_character = cv.cvtColor(found_character, cv.COLOR_RGB2GRAY)
found_array = np.array(found).astype(np.uint8)
found_array_gray = cv.cvtColor(found_array, cv.COLOR_RGB2GRAY)
found_hist = cv.calcHist([found_array],[0,1,2],None,[8,8,8],[0,256,0,256,0,256])
found_hist = cv.normalize(found_hist,found_hist).flatten()
found_hist_gray = cv.calcHist([found_array_gray],[0],None,[8],[0,256])
found_hist_gray = cv.normalize(found_hist_gray,found_hist_gray).flatten()
face_hist = cv.calcHist([face_array],[0,1,2],None,[8,8,8],[0,256,0,256,0,256])
face_hist = cv.normalize(face_hist,face_hist).flatten()
face_hist_gray = cv.calcHist([face_array_gray],[0],None,[8],[0,256])
face_hist_gray = cv.normalize(face_hist_gray,face_hist_gray).flatten()
character_hist = cv.calcHist([character_array],[0,1,2],None,[8,8,8],[0,256,0,256,0,256])
character_hist = cv.normalize(character_hist,character_hist).flatten()
character_hist_gray = cv.calcHist([character_array_gray],[0],None,[8],[0,256])
character_hist_gray = cv.normalize(character_hist_gray,character_hist_gray).flatten()
hist_compare_result_CORREL = cv.compareHist(found_hist_gray, character_hist_gray,cv.HISTCMP_CORREL)
#hist_compare_result_CHISQR = cv.compareHist(found_hist_gray, character_hist_gray,cv.HISTCMP_CHISQR)
#hist_compare_result_INTERSECT = cv.compareHist(found_hist_gray, character_hist_gray,cv.HISTCMP_INTERSECT)
#hist_compare_result_BHATTACHARYYA = cv.compareHist(found_hist_gray, character_hist_gray,cv.HISTCMP_BHATTACHARYYA)
if (hist_compare_result_CORREL+character_score.max()) > 1:
print(f"Found {file} with a score:\n match:{character_score.max()}\n hist_correl: {hist_compare_result_CORREL}\n SUM:{hist_compare_result_CORREL+character_score.max()}", file=open("/Users/user/Desktop/dbz/out.log","a+"))
【问题讨论】:
-
您是否尝试过在颜色和模板的 Alpha 通道中使用蒙版进行多尺度模板匹配?我注意到您的模板图像比例大于大图中的图标。
-
嘿,正如您在代码中看到的那样,我确实调整了模板 (character.thumbnail((153,139))) 的大小,因此它的尺寸几乎与图像中的尺寸完全相同。此外,我还尝试仅裁剪“人脸”(character.crop((22,22,94,94)),以防右下角的星号干扰正确答案。多尺度模板匹配?没听到关于它 - 我会搜索它并检查它是否可以在这里使用
-
在模板匹配中尝试使用来自模板alpha通道的掩码?
-
啊...所以要按形状匹配。好吧,虽然 alpha 通道不会只返回每个模板的帧吗?
-
来自 alpha 通道的掩码告诉 matchTemplate 在哪里不包括匹配中的像素。否则,您将匹配 alpha 通道下的任何内容,这可能会降低您的匹配分数,以便所有匹配项都相似。因此,您必须阅读模板以保留 Alpha 通道。然后将alpha通道提取为mask图像,将没有alpha通道的颜色层提取为要匹配的图像。
标签: python python-3.x opencv computer-vision