一、圖像預處理 ??
二、查找答題卡輪廓 ??
三、透視變換 ??
四、判卷與評分 ??
五、主函數
六、完整代碼+測試圖像集
總結 ??
在這篇博客中,我將分享如何使用Python結合OpenCV庫開發一個答題卡自動判卷系統。這個系統能夠自動從掃描的答題卡中提取信息、進行圖像處理、識別答案并給出評分。項目綜合運用了圖像處理的基本技術,包括圖像預處理、輪廓檢測、透視變換、二值化處理、輪廓分析等,最終實現了答題卡的自動識別和判卷功能。??
整體流程如下:
一、圖像預處理 ??
首先,我們需要加載圖像并對其進行預處理。預處理包括將圖像轉換為灰度圖,應用高斯模糊來去噪,使用Canny算法進行邊緣檢測。
def preprocess_image(image):"""圖像預處理:灰度化、高斯模糊、邊緣檢測。:param image: 輸入圖像。:return: 邊緣檢測結果。"""gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 將圖像轉換為灰度圖blurred = cv2.GaussianBlur(gray, (5, 5), 0) # 對灰度圖進行高斯模糊edged = cv2.Canny(blurred, 75, 200) # 對模糊后的圖像進行邊緣檢測return edged # 返回邊緣檢測結果
二、查找答題卡輪廓 ??
在邊緣圖像中進行輪廓檢測。通過查找輪廓,定位答題卡的四個角。確保了我們能準確地識別答題卡的位置。
-
輪廓查找:使用OpenCV的
findContours
函數查找圖像中的輪廓。 -
輪廓排序:根據輪廓的面積或位置對輪廓進行排序,便于后續處理。
-
多邊形近似:使用
approxPolyDP
函數對輪廓進行多邊形近似,找到答題卡的4個頂點。
def find_document_contour(edged):"""查找答題卡的輪廓。:param edged: 邊緣檢測結果。:return: 答題卡的4個頂點坐標。"""cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 查找輪廓cnts = imutils.grab_contours(cnts) # 兼容不同OpenCV版本的輪廓提取if len(cnts) == 0: # 如果沒有找到輪廓raise ValueError("無法找到輪廓!") # 拋出異常# 按輪廓大小排序cnts = sorted(cnts, key=cv2.contourArea, reverse=True)# 遍歷輪廓,找到矩形輪廓for c in cnts:peri = cv2.arcLength(c, True) # 計算輪廓周長approx = cv2.approxPolyDP(c, 0.02 * peri, True) # 對輪廓進行多邊形近似if len(approx) == 4: # 如果近似結果為4個點,則認為是答題卡輪廓