如何提高 canny 边缘的清晰度以改善检测?
我正在尝试检测覆盖在移动背景上的文本。我已经使用 canny 几乎完美地去除了背景,但我留下了几乎模糊的文本,我无法获得清晰的检测。
例如,对于 canny,我似乎无法获得比 96% 更好的匹配率。然而,如果我换回仅使用 matchTemplate
而不使用 canny,我可以在同一张图像上获得大约 98% 的匹配率。
我有数千张图像,其中一些像上面的图像是简单的拉丁字符,但我也有很多亚洲字符集和西里尔文字。例如,虽然上面的示例确实返回了 96% 的阳性检测结果,但下面的示例则下降了 40-50%。
我将图像加载到数组中,并生成精明的帧来运行检测。我使用 ImageGrab 获取屏幕裁剪,将其加载到 numpy 数组中,使用 GuassianBlur 模糊边缘,然后对模糊图像运行检测。然后我返回边缘来运行检测。
对于我的实际检测,我使用 matchTemplate
。我迭代加载的图像,从检测中获取最大值,如果它大于 90,我会将其打印到终端。
import cv2 as cv
import numpy as np
import glob
from PIL import ImageGrab
def loadImages(directory):
image_list = []
for i in directory:
img = cv.imread(i, cv.IMREAD_GRAYSCALE)
image_list.append((img))
return image_list
def videoLoop():
haystack_img = ImageGrab.grab(bbox=(750, 33, 1150, 70))
haystack_img_np = np.array(haystack_img )
img_blur = cv.GaussianBlur(haystack_img_np, (3,3), 0)
edges = cv.Canny(image=img_blur, threshold1=200, threshold2=500)
return edges
def shipDetection(image_list, threshold, haystack, a):
for i in image_list:
result = cv.matchTemplate(haystack, i, cv.TM_CCORR_NORMED)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
if max_val >= 90:
print(max_val)
def detection():
test = glob.glob(r"C:\Users\*.png")
images = loadImages(test)
while True:
window = videoLoop()
shipDetection(images, 0.96, window)
detection()
我想要运行检测的图像是使用它生成的;
import numpy as np
import cv2
import os
import sys
from pathlib import Path
if __name__ == "__main__":
image_dir = r"C:\test\images"
output_dir = r"C:\test\canny"
for _, _, image_names in os.walk(image_dir):
for image_name in image_names:
if '.png' in image_name:
filepath = os.path.join(image_dir, image_name)
dstpath = os.path.join(output_dir, image_name)
image = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
img_blur = cv2.GaussianBlur(image, (3,3), 0)
edges = cv2.Canny(image=img_blur, threshold1=200, threshold2=400)
cv2.imwrite(dstpath, edges)
I'm trying to detect text that's overlaid onto a moving background. I've used canny to almost perfectly remove the background but I'm left with almost blurry text that I'm not able to get clear detections on.
For example with canny, I can't seem to get better than about a 96% match. Whereas if I swap back to just using matchTemplate
without canny I can get about a 98% match on the same image.
I've got thousands of images and some like the above are simple Latin characters, but I've also got a lot of Asian character sets and Cyrillic script in there too. For example, while the above example does return a positive detection at 96% the below is down in the 40-50% mark.
I load my images into an array, and generate canny frames to run detection on. I use ImageGrab
to get a crop of the screen, load that into a numpy array, blur the edges with GuassianBlur
and then run my detection on the blurred images. I then return edges
to run detection on.
For my actual detection, I use matchTemplate
. I iterate through my loaded images, grabbing the maximum value from the detection and if it's greater than 90, I print it to the terminal.
import cv2 as cv
import numpy as np
import glob
from PIL import ImageGrab
def loadImages(directory):
image_list = []
for i in directory:
img = cv.imread(i, cv.IMREAD_GRAYSCALE)
image_list.append((img))
return image_list
def videoLoop():
haystack_img = ImageGrab.grab(bbox=(750, 33, 1150, 70))
haystack_img_np = np.array(haystack_img )
img_blur = cv.GaussianBlur(haystack_img_np, (3,3), 0)
edges = cv.Canny(image=img_blur, threshold1=200, threshold2=500)
return edges
def shipDetection(image_list, threshold, haystack, a):
for i in image_list:
result = cv.matchTemplate(haystack, i, cv.TM_CCORR_NORMED)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
if max_val >= 90:
print(max_val)
def detection():
test = glob.glob(r"C:\Users\*.png")
images = loadImages(test)
while True:
window = videoLoop()
shipDetection(images, 0.96, window)
detection()
The images I want to run detection were generated using this;
import numpy as np
import cv2
import os
import sys
from pathlib import Path
if __name__ == "__main__":
image_dir = r"C:\test\images"
output_dir = r"C:\test\canny"
for _, _, image_names in os.walk(image_dir):
for image_name in image_names:
if '.png' in image_name:
filepath = os.path.join(image_dir, image_name)
dstpath = os.path.join(output_dir, image_name)
image = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
img_blur = cv2.GaussianBlur(image, (3,3), 0)
edges = cv2.Canny(image=img_blur, threshold1=200, threshold2=400)
cv2.imwrite(dstpath, edges)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论