如何提高 canny 边缘的清晰度以改善检测?

发布于 2025-01-20 01:51:38 字数 2649 浏览 0 评论 0原文

我正在尝试检测覆盖在移动背景上的文本。我已经使用 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.

enter image description here

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.

enter image description hereenter image description here

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文