這篇文章的重點在于 模板匹配 的使用。模板匹配是計算機視覺中的一項基本技術,它通過比對輸入圖像與模板圖像的相似度,來進行目標識別。對于數字識別,特別是標準數字的識別,模板匹配非常有效。
請看效果:
文章結構
- 模板匹配的概念
- 如何裁剪圖像以提高匹配精度
- 代碼實現:數字識別
- 代碼解析
- 總結與建議
模板匹配的概念
模板匹配是一種在圖像中查找特定模板區域的方法。通過計算輸入圖像與多個模板的相似度,找到最匹配的區域。在數字識別中,這項技術通過將待識別的數字與一組模板數字進行比對,識別出最接近的數字。
如何裁剪圖像以提高匹配精度
在使用模板匹配時,圖像的預處理是至關重要的。裁剪掉不需要的部分,尤其是圖像中可能干擾匹配的區域,可以大大提高匹配的精度。確保圖像中只包含目標數字區域,從而提高識別準確率。
代碼實現:數字識別
接下來,我會分享一段我用OpenCV實現的數字識別代碼。這段代碼利用了模板匹配的方式來識別標準數字。
import cv2
import numpy as np
import os# 數字模板匹配
def img_match(input_img, template_dict):"""返回 (最佳匹配數字, 最大相似度)"""resized_img = cv2.resize(input_img, (32, 48), interpolation=cv2.INTER_LINEAR)max_val = 0.0best_num = -1for i in range(10):template = template_dict[i]result = cv2.matchTemplate(resized_img, template, cv2.TM_CCOEFF_NORMED)_, current_max, _, _ = cv2.minMaxLoc(result)if current_max > max_val:max_val = current_maxbest_num = ireturn best_num, max_val# 加載數字模板
def load_templates(template_dir):template_dict = {}for i in range(10):template_path = os.path.join(template_dir, f"{i}.png")template = cv2.imread(template_path, cv2.IMREAD_GRAYSCALE)if template is not None:_, binary_template = cv2.threshold(template, 100, 255, cv2.THRESH_BINARY_INV)resized_template = cv2.resize(binary_template, (32, 48), interpolation=cv2.INTER_LINEAR)template_dict[i] = resized_templatereturn template_dict# 主函數
def main():# 加載數字模板template_dir = "G:/pycharm/projects/opencv/num/" # 修改為你的模板路徑template_dict = load_templates(template_dir)# 打開攝像頭cap = cv2.VideoCapture(1)if not cap.isOpened():print("無法打開攝像頭")returnwhile True:ret, frame = cap.read()if not ret:breakimgContour = frame.copy()imgGray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)imgBlur = cv2.GaussianBlur(imgGray, (7, 7), 1)_, imgThresh = cv2.threshold(imgBlur, 95, 255, cv2.THRESH_BINARY_INV)edges = cv2.Canny(imgBlur, 30, 150)imgCanny = cv2.bitwise_or(edges, imgThresh)kernel = np.ones((3, 3), np.uint8)imgCanny = cv2.morphologyEx(imgCanny, cv2.MORPH_CLOSE, kernel)contours, hierarchy = cv2.findContours(imgCanny, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)for cnt in contours:area = cv2.contourArea(cnt)if area < 4500: # 像素面積小,可認為是數字x, y, w, h = cv2.boundingRect(cnt)roi = imgCanny[y:y + h, x:x + w]if roi.size == 0:continuenum, score = img_match(roi, template_dict)if score > 0.6:cv2.putText(imgContour, f"{num}", (x, y - 10),cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)cv2.imshow("Processed", imgContour)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()cv2.destroyAllWindows()if __name__ == "__main__":main()
代碼解析
1. 數字模板匹配
img_match
函數負責執行模板匹配操作。它將輸入的圖像與預先加載的數字模板進行比對,計算出匹配度,并返回最佳匹配的數字和相似度。
2. 加載模板
load_templates
函數從指定路徑加載數字模板,模板圖像會經過二值化處理并調整到統一的尺寸,確保模板能夠適應各種輸入圖像。
3. 圖像預處理
在主函數中,我們首先通過攝像頭讀取圖像,并進行一些常見的圖像預處理操作,包括灰度化、模糊化和邊緣檢測。然后,我們使用 cv2.findContours
函數提取圖像中的數字區域。
4. 匹配與識別
通過 img_match
函數對每一個數字區域進行模板匹配,若匹配的相似度大于設定的閾值(例如0.6),則將識別的數字顯示在圖像上。
總結與建議
通過模板匹配,我們能夠快速、準確地識別標準數字,適用于數字識別的基礎場景。對于更復雜的場景,如手寫數字或不同字體的數字,可能需要更先進的算法,如深度學習模型。
希望這篇文章能夠幫助你理解OpenCV中模板匹配的使用方法。如果你有任何問題或改進建議,歡迎在評論區留言討論。