首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >A simple method for identifying objective questions_2

A simple method for identifying objective questions_2

原创
作者头像
Swing Dunn
发布2025-10-18 17:04:38
发布2025-10-18 17:04:38
300
举报
文章被收录于专栏:答题卡识别答题卡识别

The whole source code of last page: https://cloud.tencent.com/developer/article/2578271

代码语言:txt
复制
import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

img_path = './img7/2.jpg'
template_block_pos = [(30,11), (77,11), (124, 11), (172, 11),
                      (30,41), (77,41), (124, 41), (172, 41),
                      (30,68), (77,68), (124, 68), (172, 68),
                      (30,97), (77,97), (124, 97), (172, 97),
                      (30,126), (77,126), (124, 126), (172, 126)]
template_block_size =(30,18)

ans_area = ((9, 11+15),(9, 41+15),(9, 68+15),(9, 97+15),(9, 126+15))

def calculate_next_char(base_char, offset):
    base_ascii = ord(base_char)
    new_ascii = base_ascii + offset
    new_char = chr(new_ascii)
    return new_char

def img_show(img):
    cv2.namedWindow("default", cv2.WINDOW_FREERATIO)
    cv2.imshow("default", img)
    cv2.waitKey(0)
    cv2.destroyWindow("default")

def plot_show(arr):
    data = np.array([arr])
    #x = np.arange(len(data[0][0]))
    x = np.array(['A', 'B', 'C', 'D'])

    # 绘制折线图
    plt.figure(figsize=(10, 6))  
    for i in range(data.shape[1]): 
        plt.plot(x, data[0][i], marker='o', label=f'ques_id {i+1}') 

    # 设置图形的标题和坐标轴标签
    plt.title('Line Plot of Fill_in rate')
    plt.xlabel('Opt item')
    plt.ylabel('Input rate')
    plt.legend()
    plt.grid(True)
    plt.show()

def main():
    ori_img = cv2.imread(img_path, cv2.IMREAD_ANYCOLOR)
    display_img = ori_img.copy()

    gray = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)

    #增强图像对比度 
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    gray_c = clahe.apply(gray)
    #高斯滤波
    gray_c = cv2.GaussianBlur(gray_c, (3, 3), 0)

    # img_show(ori_img)
    # img_show(gray_c)

    # 二值化处理,使用OTSU自动阈值
    g_threshold, binary = cv2.threshold(gray_c, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    img_show(binary)

    display_bin = cv2.cvtColor(binary, cv2.COLOR_GRAY2BGR)
    input_rate = []
    for i in range(len(template_block_pos)):
        block_lt_pt = template_block_pos[i]
        ex_block_ltpt = (block_lt_pt[0] - 6, block_lt_pt[1] - 3)
        ex_block_size =  (template_block_size[0] + 12, template_block_size[1] + 6)
        ex_block_rbpt = (ex_block_ltpt[0] + ex_block_size[0] , ex_block_ltpt[1] + ex_block_size[1])

        cv2.rectangle(display_bin, (ex_block_ltpt[0], ex_block_ltpt[1]),  (ex_block_rbpt[0] , ex_block_rbpt[1]), (0,255,0), 1)
        ex_block_arr = binary[ex_block_ltpt[1] : ex_block_rbpt[1], ex_block_ltpt[0] : ex_block_rbpt[0]]
        non_zero_count = np.count_nonzero(ex_block_arr)
        input_rate.append(non_zero_count / (ex_block_size[0] * ex_block_size[1]))
    #img_show(display_bin)
    input_rate_arr =  np.reshape(input_rate,(5, 4))
    # print("填涂情况统计数据:")
    # print(input_rate_arr)
    data = np.array([input_rate])
    data_reshaped = data.T

    # 创建KMeans对象,设置聚类数为2
    kmeans = KMeans(n_clusters=2, random_state=0)
    kmeans.fit(data_reshaped)
    labels = kmeans.labels_

    print("Cluster labels:", labels)
    ans = np.reshape(labels,(5,4))
    ans = np.where(ans > 0 , 0,1)
    print('result: ', ans)

    #plot_show(input_rate_arr)
    for i in range(ans.shape[0]):
        for j in range(ans.shape[1]):
            if(ans[i][j] > 0 ):
                str_answer = calculate_next_char('A', j)
                font = cv2.FONT_HERSHEY_SIMPLEX
                cv2.putText(display_img,str_answer,ans_area[i],font,0.5,(0,0,255),2,cv2.LINE_AA)
   
    img_show(display_img)

if __name__ == '__main__':
    main()

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档