Python 퀴즈 카드 인식 및 점수 구현 코드 제시

안녕하세요,우 스 꽝 스 러 운 연구소 입 니 다.우리 이미지 처리 시 리 즈 를 본 친 구 는 답안 지 식별 기 사 를 알 아야 한다.그 중에서 opencv 프레임 워 크 를 이용 하여 답안 지 작성 구역 의 식별 을 완벽 하 게 실현 했다.백 스테이지 에 친구 들 이 옵션 의 옳 고 그 름 을 판단 하고 점 수 를 매 기 는 기능 을 보완 하 기 를 원 하 는데 이번 기 에 우 리 는 이 를 실현 하 겠 습 니 다.
그럼 우리 예전 의 코드 원 리 를 복습 해 봅 시다.우 리 는 사진 소재 에 대해 그 레이스 케 일 처리,투시 변환,윤곽 검 측,부식 팽창 처리,지역 분할,테두리 계산,지역 계산 을 해 야 한다.실제로 우 리 는 픽 셀 면적 의 여과,채 워 넣 기 영역 최적화 와 옵션 좌 표를 얻어 답안 카드 의 식별 을 완성 했다.
소재:
在这里插入图片描述
예.우 리 는 먼저 답안 지 를 분리 해서 방해 항목 을 제거 한 후에 서로 다른 구역 에 라벨 을 붙인다.우리 의 답안 지 는 위 에서 아래로 정렬 되 어 있다.그러면 우리 가 얻 은 채 워 넣 기 항목 의 x 좌 표 는 바로 가로 좌표 로 도움 이 된다.A~E 를 선택 하면 다섯 개의 다른 구역 을 차지 할 것 입 니 다.우 리 는 이미 다른 지역 에 라벨 을 달 았 다.나머지 는 우리 에 게 맡 긴 if 판단 문 입 니 다.이때 우 리 는 이미 매 립 항 에 실제 적 인 의 미 를 부여 했다.픽 셀 좌표 에서 실제 적 인 의 미 를 가 진 옵션 으로 전환 한 것 이다.
그럼 y 좌 표 는 소 용이 없 나 요?뿐만 아니 라위의 처 리 를 통 해 우 리 는 단지 매 립 구역 에 대응 하 는 옵션 을 얻 었 을 뿐이다.하지만 우 리 는 아직 정렬 을 하지 않 았 다.무질서 한 옵션 은 무의미 하 다 는 것 을 모두 가 알 고 있다.방금 우리 가 이 문제 카드 의 문제 번호 순 서 는 위 에서 아래로 내 려 왔 다 고 말 했다.우리 가 옵션 을 옮 겨 다 닐 때 x,y 좌 표를 동시에 얻 을 수 있 기 때문에 우 리 는 얻 은 좌 표를 맞 출 수 있 습 니 다.
*8195:8195:그 중에서 가로 세로 좌 표 는 각각 두 개의 list 에 기입 한 다음 에 zip 방법 으로 list 를 합병 합 니 다.이때 우 리 는 모든 list 의 두 번 째 요소,즉 세로 좌표 에 따라 작은 것 에서 큰 것 으로 정렬 하면 정확 한 순 서 를 얻 을 수 있다.
이 때 에 야 우 리 는 진정 으로 필요 한 데 이 터 를 얻 었 다.즉,수험생 이 작성 한 옵션 순 서 는 list 를 새로 만들어 정 답 을 놓 고 수험생 의 답안 과 비교 하여 수험생 의 정 답 률 을 계산 하여 점 수 를 주 는 것 이다.
좋 습 니 다.생각 이 뚜렷 하고 코드 가 올 라 갑 니 다!

import cv2
import numpy as np

path = './test_01.png'
img = cv2.imread(path)

imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgBlur = cv2.GaussianBlur(imgGray,(3,3),1)
imgCanny = cv2.Canny(imgBlur,100,120)

cv2.imshow("O", imgCanny)

imgContour = img.copy()

cnts = cv2.findContours(imgCanny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
for cnt in cnts:
    area = cv2.contourArea(cnt)
    #            
    #print(area)
#
if area >= 500:
    cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3)
    peri = cv2.arcLength(cnt, True)
    #         
    approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)
    # approx              ,            
    #       list,      ,           
    #print(approx)
    a1,a2,a3,a4 = list(approx[0][0]),list(approx[1][0]),list(approx[2][0]),list(approx[3][0])

#cv2.imshow("Canny Image",imgContour)

mat1 = np.array([a1,a2,a3,a4],dtype=np.float32)

#    
#      
width = 402#int(((a4[0]-a1[0])+(a3[0]-a2[0]))/2)
height = 518#int(((a2[1]-a1[1])+(a3[1]-a4[1]))/2)

#        
new_a1 = [0,0]
new_a2 = [0,height]
new_a3 = [width,height]
new_a4 = [width,0]

mat2 = np.array([new_a1,new_a2,new_a3,new_a4],dtype=np.float32)
#      
mat3 = cv2.getPerspectiveTransform(mat1,mat2)

#      
res = cv2.warpPerspective(imgCanny,mat3,(width,height))
res1 = cv2.warpPerspective(img,mat3,(width,height))

imgxx = cv2.cvtColor(res1,cv2.COLOR_BGR2GRAY)
binary = cv2.threshold(imgxx,0,255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU )[1]
#    
#cv2.imshow("Output",res1)

cntss = cv2.findContours(res, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
for cnt1 in cntss:
    area1 = cv2.contourArea(cnt1)
    #            
    #print(area)
#
    if area1 >= 1500 and area1<=1700:
        #         
        cv2.drawContours(binary, cnt1, -1, (0, 0, 0), 10)

        kernel = np.ones((5, 5), np.uint8)
        imgDialation = cv2.dilate(binary, kernel, iterations=1)

cv2.imshow("Out", imgDialation)

cntsss = cv2.findContours(imgDialation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]

l1 = []
l2 = []
l3 = ['B','E','A','D','B']

for cnt2 in cntsss:
    area2 = cv2.contourArea(cnt2)
            #print(area)

    if area2 <= 1200 and 800<=area2:
                #cv2.drawContours(res1, cnt, -1, (0, 255, 0), 5)
                #   
        peri = cv2.arcLength(cnt2, True)
                #         
        approx1 = cv2.approxPolyDP(cnt2, 0.02 * peri, True)

        x, y, w, h = cv2.boundingRect(approx1)
                #    
        #print(x+w//2,y+h//2)

        m = x+w//2
        n = y+h//2
        l1.append(m)
        l2.append(n)
        #        , x,y    。
        mix1 = list(zip(l1,l2))
        #          ,  y       。
        #              。
        mix1.sort(key=lambda x: x[1])

        if 400>x>80 and 50<y<350:
            cv2.rectangle(res1, (x, y), (x + w, y + h), (0, 0, 255), 2)
            #  
            # (  ,x.y  ,  ,  ,    )
            cv2.circle(res1, (x+w//2,y+h//2), 1, (255, 0, 0), 5)

l4 = []
for i in mix1:
    if 75 < i[0] < 130:
        print("A")
        l4.append('A')
    elif 130 < i[0] < 185:
        print("B")
        l4.append('B')
    elif 185 < i[0] < 240:
        print("C")
        l4.append('C')
    elif 240 < i[0] < 295:
        print("D")
        l4.append('D')
    elif 295 < i[0] < 350:
        print("E")
        l4.append('E')

print('    :',l3)
print('    ',l4)


h = 0
for i in range(0, len(l3)):
    if l3[i] == l4[i]:
        h=h+1
print('  :',str(h/5*100)+' ')

cv2.imshow("cc Image",res1)

cv2.imshow("dd Image",binary)

cv2.waitKey(0)
실행 결과:
在这里插入图片描述
在这里插入图片描述
*8195°이상 은 두 개의 사진 소재 의 운행 결과 로 우 리 는 그 중의 일부분 만 방출 한다.나머지 소 재 는 모두 스스로 실험 한다.
*8195 에서 볼 수 있 듯 이 프로그램 은 수험생 이 작성 한 답안 지 를 성공 적 으로 식별 하고 수험생 의 답안,정 답 과 수험생 의 마지막 점 수 를 제시 했다.
『8195』종합 기능 이 실현 되 고 임 무 를 완성 합 니 다.여러분 배 웠 어 요?
이상 은 파 이 썬 이 답안 지 를 식별 하고 점 수 를 주 는 상세 한 내용 입 니 다.파 이 썬 이 답안 지 를 식별 하 는 데 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기