python學習 - 使用OpenCV庫(cv2)和imutils庫實現輔助答題卡判別

測試數據見文章頂部位置資源!!!

使用了OpenCV庫(cv2)和imutils庫。代碼的主要目的是處理圖像中的問題,如識別圖像中的文字,并對其進行分析和排序。
輔助答題卡判別

# -*- coding:utf-8 -*-
from imutils.perspective import four_point_transform
# 圖像處理函數,對OpenCV的簡化
from imutils import contours
# 支持大量的維度數組與矩陣運算
import numpy as np
# OpenCV庫(cv2)
import cv2 as cv
# https://github.com/qindongliang/answer_sheet_scan
ANSWER_KEY_SCORE = {0: 1, 1: 4, 2: 0, 3: 3, 4: 1}ANSWER_KEY = {0: "A", 1: "B", 2: "C", 3: "D", 4: "E"}# 加載一個圖片到opencv中
img = cv.imread('test01.jpg')cv.imshow("orgin", img)# 轉化成灰度圖片
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)cv.imshow("gray", gray)gaussian_bulr = cv.GaussianBlur(gray, (5, 5), 0)  # 高斯模糊cv.imshow("gaussian", gaussian_bulr)edged = cv.Canny(gaussian_bulr, 75, 200)  # 邊緣檢測,灰度值小于2參這個值的會被丟棄,大于3參這個值會被當成邊緣,在中間的部分,自動檢測cv.imshow("edged", edged)# 尋找輪廓
image, cts, hierarchy = cv.findContours(edged.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)# 給輪廓加標記,便于我們在原圖里面觀察,注意必須是原圖才能畫出紅色,灰度圖是沒有顏色的
# cv.drawContours(img, cts, -1, (0,0,255), 3)# 按面積大小對所有的輪廓排序
list = sorted(cts, key=cv.contourArea, reverse=True)print("尋找輪廓的個數:", len(cts))
cv.imshow("draw_contours", img)# 正確題的個數
correct_count = 0for c in list:# 周長,第1個參數是輪廓,第二個參數代表是否是閉環的圖形peri = 0.01 * cv.arcLength(c, True)# 獲取多邊形的所有定點,如果是四個定點,就代表是矩形approx = cv.approxPolyDP(c, peri, True)# 打印定點個數print("頂點個數:", len(approx))if len(approx) == 4:  # 矩形# 透視變換提取原圖內容部分ox_sheet = four_point_transform(img, approx.reshape(4, 2))# 透視變換提取灰度圖內容部分tx_sheet = four_point_transform(gray, approx.reshape(4, 2))cv.imshow("ox", ox_sheet)cv.imshow("tx", tx_sheet)# 使用ostu二值化算法對灰度圖做一個二值化處理ret, thresh2 = cv.threshold(tx_sheet, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)cv.imshow("ostu", thresh2)# 繼續尋找輪廓r_image, r_cnt, r_hierarchy = cv.findContours(thresh2.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)print("找到輪廓個數:", len(r_cnt))# 使用紅色標記所有的輪廓# cv.drawContours(ox_sheet,r_cnt,-1,(0,0,255),2)# 把所有找到的輪廓,給標記出來questionCnts = []for cxx in r_cnt:# 通過矩形,標記每一個指定的輪廓x, y, w, h = cv.boundingRect(cxx)ar = w / float(h)if w >= 20 and h >= 20 and ar >= 0.9 and ar <= 1.1:# 使用紅色標記,滿足指定條件的圖形# cv.rectangle(ox_sheet, (x, y), (x + w, y + h), (0, 0, 255), 2)# 把每個選項,保存下來questionCnts.append(cxx)cv.imshow("ox_1", ox_sheet)# 按坐標從上到下排序questionCnts = contours.sort_contours(questionCnts, method="top-to-bottom")[0]# 使用np函數,按5個元素,生成一個集合for (q, i) in enumerate(np.arange(0, len(questionCnts), 5)):# 獲取按從左到右的排序后的5個元素cnts = contours.sort_contours(questionCnts[i:i + 5])[0]bubble_rows = []# 遍歷每一個選項for (j, c) in enumerate(cnts):# 生成一個大小與透視圖一樣的全黑背景圖布mask = np.zeros(tx_sheet.shape, dtype="uint8")# 將指定的輪廓+白色的填充寫到畫板上,255代表亮度值,亮度=255的時候,顏色是白色,等于0的時候是黑色cv.drawContours(mask, [c], -1, 255, -1)# 做兩個圖片做位運算,把每個選項獨自顯示到畫布上,為了統計非0像素值使用,這部分像素最大的其實就是答案mask = cv.bitwise_and(thresh2, thresh2, mask=mask)# cv.imshow("c" + str(i), mask)# 獲取每個答案的像素值total = cv.countNonZero(mask)# 存到一個數組里面,tuple里面的參數分別是,像素大小和答案的序號值# print(total,j)bubble_rows.append((total, j))bubble_rows = sorted(bubble_rows, key=lambda x: x[0], reverse=True)# 選擇的答案序號choice_num = bubble_rows[0][1]print("答案:{} 數據: {}".format(ANSWER_KEY.get(choice_num), bubble_rows))fill_color = None# 如果做對就加1if ANSWER_KEY_SCORE.get(q) == choice_num:fill_color = (0, 255, 0)  # 正確 綠色correct_count = correct_count + 1else:fill_color = (0, 0, 255)  # 錯誤 紅色cv.drawContours(ox_sheet, cnts[choice_num], -1, fill_color, 2)cv.imshow("answer_flagged", ox_sheet)text1 = "total: " + str(len(ANSWER_KEY)) + ""text2 = "right: " + str(correct_count)text3 = "score: " + str(correct_count * 1.0 / len(ANSWER_KEY) * 100) + ""font = cv.FONT_HERSHEY_SIMPLEXcv.putText(ox_sheet, text1 + "  " + text2 + "  " + text3, (10, 30), font, 0.5, (0, 0, 255), 2)cv.imshow("score", ox_sheet)breakcv.waitKey(0)
# -*- coding:utf-8 -*-
from imutils.perspective import four_point_transform
from imutils import contours
import numpy as np
import cv2 as cv# 加載原圖,可在項目imgs/example02目錄下找到
img = cv.imread("test01.jpg")# cv.resizeWindow("enhanced", 240, 280);
# 打印原圖
cv.imshow("orgin", img)# 灰度化
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# 打印灰度圖
cv.imshow("gray", gray)# 高斯濾波,清除一些雜點
blur = cv.GaussianBlur(gray, (3, 3), 0)# 自適應二值化算法
thresh2 = cv.adaptiveThreshold(blur, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 131, 4)# 打印二值化后的圖
cv.imshow("thresh2", thresh2)# 尋找輪廓
image, cts, hierarchy = cv.findContours(thresh2, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)# 打印找到的輪廓
print("輪廓數:", len(cts))# 對拷貝的原圖進行輪廓標記
contour_flagged = cv.drawContours(img.copy(), cts, -1, (0, 0, 255), 3)
# 打印輪廓圖
cv.imshow("contours_flagged", contour_flagged)
# 按像素面積降序排序
list = sorted(cts, key=cv.contourArea, reverse=True)# 遍歷輪廓
for ct in list:# 周長,第1個參數是輪廓,第二個參數代表是否是閉環的圖形peri = 0.01 * cv.arcLength(ct, True)# 獲取多邊形的所有定點,如果是四個定點,就代表是矩形approx = cv.approxPolyDP(ct, peri, True)# 只考慮矩形if len(approx) == 4:# 從原圖中提取所需的矯正圖片ox = four_point_transform(img, approx.reshape(4, 2))# 從原圖中提取所需的矯正圖片tx = four_point_transform(gray, approx.reshape(4, 2))# 打印矯正后的灰度圖cv.imshow("tx", tx)# 對矯正圖進行高斯模糊blur = cv.GaussianBlur(tx, (3, 3), 0)# 對矯正圖做自適應二值化thresh2 = cv.adaptiveThreshold(blur, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 131, 4)# 打印矯正后的二值化圖cv.imshow("tx_thresh2", thresh2)# 獲取輪廓r_image, r_cts, r_hierarchy = cv.findContours(thresh2, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)# 打印得到輪廓數量print("第二層輪廓數:", len(r_cts))# 用于存儲答案的python list變量question_list = []for r_ct in r_cts:# 轉為矩形,分別獲取 x,y坐標,及矩形的寬和高x, y, w, h = cv.boundingRect(r_ct)# 過濾掉不符合答案坐標和長寬的選項if x > 2 and y > 2 and w > 20 and h > 20:# cv.drawContours(ox, r_ct, -1, (0, 0, 255), 1)question_list.append(r_ct)print("答案總數:", len(question_list))# 按坐標從上到下排序questionCnts = contours.sort_contours(question_list, method="top-to-bottom")[0]#  使用np函數,按5個元素,生成一個集合for (q, i) in enumerate(np.arange(0, len(questionCnts), 5)):# 每一個行5個答案,從左到右排序cnts = contours.sort_contours(questionCnts[i:i + 5])[0]# 存儲一行題里面的每個答案ans_list = []for (j, cc) in enumerate(cnts):# 生成全黑畫布mask = np.zeros(thresh2.shape, dtype="uint8")# 將每一個答案按輪廓寫上去,并將填充顏色設置成白色tpp = cv.drawContours(mask, [cc], -1, 255, -1)# 兩個圖片做位運算mask = cv.bitwise_and(thresh2, thresh2, mask=mask)# 統計每個答案的像素total = cv.countNonZero(mask)# 添加到集合里面ans_list.append((total, j))# 按像素大小排序ans_list = sorted(ans_list, key=lambda x: x[0], reverse=True)max_ans_num = ans_list[0][1]max_ans_size = ans_list[0][0]print("答案序號:", max_ans_num, "列表:", ans_list)# 給選中答案,標記成紅色cv.drawContours(ox, cnts[max_ans_num], -1, (0, 0, 255), 2)cv.imshow("answer_flagged", ox)# 最大的輪廓就是我們想要的,之后的就可以結束循環了break# 阻塞等待窗體關閉
cv.waitKey(0)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/23646.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/23646.shtml
英文地址,請注明出處:http://en.pswp.cn/web/23646.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python實現郵箱轟炸機

最近在學計算機網絡看到套接字的練習 于是應用SMTP協議寫了個發送郵箱的玩玩 可以發一大堆垃圾郵件給對方 其中參考了 關于發郵件報錯535 Error&#xff1a;authentication failed解決方法http://t.csdnimg.cn/Bc0Dq 已經查詢如何獲取網易郵箱客戶端授權碼 base64編碼 i…

Mybatis05-一對多和多對一處理

多對一和一對多 多對一 多對一的理解&#xff1a; 多個學生對應一個老師 如果對于學生這邊&#xff0c;就是一個多對一的現象&#xff0c;即從學生這邊關聯一個老師&#xff01; 結果映射&#xff08;resultMap&#xff09;&#xff1a; association 一個復雜類型的關聯&…

在線Logo背景去除:pixian.ai

文章目錄 簡介特色 簡介 pixian.ai是一款智能圖片背景去除工具&#xff0c;進入網頁后&#xff0c;會非常醒目地提示你準備【Free】還是【Paid】&#xff0c;這點就非常好&#xff0c;不向有一些網站&#xff0c;主打免費使用&#xff0c;但時不時彈出“免費注冊”&#xff0c…

【微信小程序】連接藍牙設備

1、檢查小程序是否授權藍牙功能 initBluetooth() {const that thiswx.getSetting({success: (res) > {if (res.authSetting.hasOwnProperty(scope.bluetooth)) {//scope.bluetooth屬性存在&#xff0c;且為falseif (!res.authSetting[scope.bluetooth]) {wx.showModal({tit…

Python 連接 MySQL 及 SQL增刪改查(主要使用sqlalchemy)

目錄 一、環境 二、MySQL的連接和使用 2.1方式一&#xff1a;sql為主 2.1.1創建連接 2.1.2 表結構 2.1.3 新增數據 ?編輯 2.1.4 查看數據 ?編輯 2.1.5 修改數據 2.1.6 刪除數據 2.2方式二&#xff1a;orm對象關系映射 2.2.1 mysql連接 2.2.2 創建表 2.2.3 新增…

windows 安裝pnpm

安裝Node.js&#xff1a; 確保系統上已安裝Node.js。pnpm需要Node.js來運行。如果尚未安裝Node.js&#xff0c;請從其官方網站下載并安裝適用于Windows的最新版本。 安裝pnpm&#xff1a; 打開命令行工具&#xff08;如CMD、PowerShell或Git Bash&#xff09;。使用npm&…

解鎖機器學習的無限可能:深入探究scikit-learn的強大功能

解鎖機器學習的無限可能&#xff1a;深入探究scikit-learn的強大功能 第一部分&#xff1a;背景和功能介紹 在數據科學和機器學習領域&#xff0c;scikit-learn&#xff08;簡稱sklearn&#xff09;是一個廣泛使用的Python庫。它提供了簡單高效的工具用于數據挖掘和數據分析&a…

【Python短期內快速掌握學習人工智能知識能力】:從零到入門的NLP學習秘籍

??我叫憶_恒心&#xff0c;一名喜歡書寫博客的研究生&#x1f468;?&#x1f393;。 如果覺得本文能幫到您&#xff0c;麻煩點個贊&#x1f44d;唄&#xff01; 近期會不斷在專欄里進行更新講解博客~~~ 有什么問題的小伙伴 歡迎留言提問歐&#xff0c;喜歡的小伙伴給個三連支…

Echarts 在折線圖的指定位置繪制一個圖標展示

文章目錄 需求分析需求 在線段交匯處用一個六邊形圖標展示 分析 可以使用 markPoint 和 symbol 屬性來實現。這是一個更簡單和更標準的方法來添加標記點在運行下述代碼后,你將在瀏覽器中看到一個折線圖,其中在 [3, 35] (即圖表中第四個數據點 Thu 的 y 值為 35 的位置)處…

Java反射Reflect機制詳解

文章目錄 引言反射的基本概念反射基本原理反射應用場景反射基本使用獲取類的Class對象獲取構造方法并實例化對象獲取和調用方法獲取和修改字段反射工具類 反射源碼解讀獲取Class對象的源碼調用方法的源碼 反射優缺點優點缺點 為什么需要反射總結 引言 Java反射是Java語言中的一…

【干貨】視頻文件抽幀(opencv和ffmpeg方式對比)

1 廢話不多說&#xff0c;直接上代碼 opencv方式 import time import subprocess import cv2, os from math import ceildef extract_frames_opencv(video_path, output_folder, frame_rate1):"""使用 OpenCV 從視頻中抽取每秒指定幀數的幀,并保存到指定文件夾…

linux系統使用達夢數據庫

在Linux系統中使用達夢數據庫&#xff0c;首先需要確保已經正確安裝了達夢數據庫軟件。以下是一個基本的使用示例&#xff0c;假設您已經安裝了達夢數據庫并且配置好了相關環境變量。 連接到數據庫&#xff1a; 使用 dsql 命令連接到數據庫 dsql -h hostname -u username -p…

寶貝,帶上WebAssembly,換個姿勢來優化你的前端應用

在你沒崛起之前,臉是用來丟的 大家好,我是柒八九。一個專注于前端開發技術/Rust及AI應用知識分享的Coder 此篇文章所涉及到的技術有 WebAssemblyRustWeb Worker(comlink)wasm-packPhotonffmpeg.wasm腳手架生成前端項目因為,行文字數所限,有些概念可能會一帶而過亦或者提供對…

BOM是什么東西

BOM&#xff08;Byte Order Mark&#xff0c;字節順序標記&#xff09;是一個Unicode字符&#xff0c;通常出現在文本文件的開頭。它的作用包括以下幾個方面&#xff1a; 1. 指示文件的編碼方式 BOM可以幫助軟件識別文本文件使用的字符編碼。不同的編碼方式可能會使用不同的B…

經濟與安全兼顧:茶飲店購買可燃氣體報警器的價格考量

可燃氣體報警器在如今的社會中扮演著至關重要的角色。它們用于檢測環境中的可燃氣體濃度&#xff0c;及早發現潛在的火災隱患&#xff0c;保護人們的生命和財產安全。 在這篇文章中&#xff0c;佰德將介紹可燃氣體報警器的安裝、檢定以及價格&#xff0c;通過實際案例和數據&a…

PCL 生成空間橢圓點云

目錄 一、算法原理二、代碼實現三、結果展示本文由CSDN點云俠原創,原文鏈接。如果你不是在點云俠的博客中看到該文章,那么此處便是不要臉的爬蟲。 一、算法原理 設橢圓在 X O Y XOY XOY平面上,參數方程為:

怎么保障TikTok直播網絡穩定?

TikTok&#xff0c;這個近年來風靡全球的社交媒體平臺&#xff0c;已成為電商引流的新方向&#xff0c;尤其是其直播功能。然而&#xff0c;對于打算進軍TikTok直播領域的商家和主播而言&#xff0c;確保網絡穩定無疑是首要任務。那么&#xff0c;TikTok直播專線究竟是什么呢&a…

牛啊后續:如何一行C#代碼實現解析類型的Summary注釋(可用于數據字典快速生成)...

前言&#xff1a;下午有小伙伴要求&#xff0c;讓我繼續做個解析實體類注釋信息的內容。所以我也順便加入進來。以下開始正文實戰操作&#xff1a; 項目需要勾選輸出api文檔文件。這樣就可以讓所有實體類的summary信息被寫入到輸出目錄下。如果有多個xml文件也沒關系&#xff0…

小程序 UI 風格美不勝收

小程序 UI 風格美不勝收 小程序 UI 風格美不勝收

PostgreSQL的視圖pg_stat_replication

PostgreSQL的視圖pg_stat_replication pg_stat_replication 是 PostgreSQL 提供的一個系統視圖&#xff0c;用于顯示主服務器上當前正在進行的復制會話的信息。它可以幫助數據庫管理員監控和管理主從復制的狀態&#xff0c;確保數據的正確同步和高可靠性。 pg_stat_replicati…