current position:Home>Good guy, another Python training project

Good guy, another Python training project

2022-05-15 06:13:11Program ape Li Xun Tian

I'll bring you another one today Python + Opencv My hands training project .

Identify answer cards , Adopt this idea , You can try all kinds of answer cards .

 Insert picture description here
Ideas :

  • Read in the picture , Do some preprocessing .
  • Carry out contour detection , Then find the largest outline of the picture , It's the answer sheet .
  • Do perspective transformation , To remove more than part of the answer sheet , And the answer sheet can be corrected .
  • Check the contour again , Locate each option .
  • Sort the option circles according to the vertical coordinates first , Then sort by row coordinates , In this way, each option wheel is obtained from left to right and from top to bottom * profile .
  • Check the outline of each option , If there are many white points in the outline of an option , Indicates that this option is selected , Otherwise, you won't be selected .

See the process in detail :

1、 Preprocessing ( Denoise , Grayscale , Two valued )

img = cv2.imread("1.png",1)
# Gaussian denoising 
img_gs = cv2.GaussianBlur(img,[5,5],0)
#  Go gray 
img_gray = cv2.cvtColor(img_gs,cv2.COLOR_BGR2GRAY)
#  Adaptive binarization 
_,binary_img = cv2.threshold(img_gray,0,255,cv2.THRESH_OTSU|cv2.THRESH_BINARY)

notes : cv2.THRESH_OTSU|cv2.THRESH_BINARY, This parameter refers to the adaptive threshold + Inverse binarization , When making adaptive threshold, the threshold should be set to 0

 Insert picture description here
2、 Contour detection

#  Find the outline 
contours, hierarchy = cv2.findContours(binary_img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
#  Sort according to the area of the contour from large to small 
cnts = sorted(contours,key = cv2.contourArea,reverse=True)
#  Draw outline 
draw_img = cv2.drawContours(img.copy(),cnts[0],-1,(0,255,255),2)

notes : findContours function , The incoming image should be a binary image ,cv2.RETR_EXTERNAL It means that only the external contour is detected ,cv2.CHAIN_APPROX_NONE Refers to all points on the return contour .

 Insert picture description here

#  The outline is approximate 
#  threshold , Generally, it is the length of the contour 2%
alpha = 0.02*cv2.arcLength(cnts[0],True)
approxCurve = cv2.approxPolyDP(cnts[0],alpha,True)
draw_img = cv2.drawContours(img.copy(),[approxCurve],-1,(255,0,0),2)

The purpose of contour approximation here is , The previously detected contour looks like a polygon , In fact, it is essentially just a point set .

cv2.approxPolyDP(contour,epsilon,True), Polygonal approximation , The first parameter is the point set , The second parameter is precision ( The maximum distance between the boundary point of the original contour and the fitting polygon ), The third parameter refers to whether the newly generated contour needs to be closed , Return value approxCurve Is the point set of the polygon ( Sort counterclockwise ).

Functions similar to this function include cv2.boundingRect( Rectangular bounding box )cv2.minAreaRect( Minimum bounding rectangle ),cv2.minEnclosingCircle( Minimum enclosing circle )cv2.filtEllipse( Best fit ellipse )cv2.filtLine( Optimal fitting line ),cv2.minEnclosingTriangle( Minimum outsourcing triangle ).

 Insert picture description here
3、 Perspective transformation

# Perspective transformation 
#  The four vertices of the rectangle are approxCurve[0][0],approxCurve[1][0],approxCurve[2][0],approxCurve[3][0]
#  Each represents a rectangle TL,BL,BR,TR Four points 
a1 = list(approxCurve[0][0])
a2 = list(approxCurve[1][0])
a3 = list(approxCurve[2][0])
a4 = list(approxCurve[3][0])
#  Original matrix 
mat1 = np.array([a1,a2,a3,a4],dtype = np.float32)

#  Calculate the of the rectangle w and h
w1 = int(np.sqrt((a1[0]-a4[0])**2+(a1[1]-a4[1])**2))
w2 = int(np.sqrt((a2[0]-a3[0])**2+(a2[1]-a3[1])**2))
h1 = int(np.sqrt((a1[0]-a2[0])**2+(a1[1]-a2[1])**2))
h2 = int(np.sqrt((a3[0]-a4[0])**2+(a3[1]-a4[1])**2))
#  Calculate the coordinates after perspective transformation 
new_a1 = [0,0]
new_a2 = [0,h]
new_a3 = [w,h]
new_a4 = [w,0]
#  Objective matrix 
mat2 = np.array([new_a1,new_a2,new_a3,new_a4],dtype = np.float32)
#  Perspective transformation matrix 
mat = cv2.getPerspectiveTransform(mat1,mat2)
#  Do perspective transformation 
res = cv2.warpPerspective(img,mat,(w,h))

 Insert picture description here
Calculation steps of perspective transformation :

1. First, get the four vertices of the original polygon , Pay attention to vertex order .

2. Then construct the original vertex matrix .

3. Calculate the length and width of the rectangle , Construct the transformed target matrix .

4. Obtain the perspective transformation matrix from the original matrix to the target matrix

5. Do perspective transformation

4、 Contour detection , Test each option

res_gray = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)
_,binary_res = cv2.threshold(res_gray,0,255,cv2.THRESH_OTSU|cv2.THRESH_BINARY_INV)
contours = cv2.findContours(binary_res,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)[0]
dst = cv2.drawContours(res.copy(),contours,-1,(0,0,255),1)

 Insert picture description here
Filter option profile :

#  Choose the right profile 
def check(contours):
    ans = []
    for i in contours:
        area = float(cv2.contourArea(i))
        length = float(cv2.arcLength(i,True))
        if area<=0 or length<=0:
        if area/length >7.05 and area/length<10.5:
    return ans
ans_contours = check(contours)
dst_new = cv2.drawContours(res.copy(),ans_contours,-1,(0,255,255),3  )

 Insert picture description here
5、 Circumscribed circle for drawing outline , Sort , Locate each option

#  Traverse every circular contour , Circumscribe 
circle = []
for i in ans_contours:
    (x,y),r = cv2.minEnclosingCircle(i)
    center = (int(x),int(y))
    r = int(r)
#  Sort according to the horizontal coordinates of the circumscribed circle center[1], That is, the height of the center of the circle h, perhaps y coordinate 
circle.sort(key = lambda x:x[0][1])
A = []
for i in range(1,6):
    now = circle[(i-1)*5:i*5]
    now.sort(key = lambda x:x[0][0])

Each option is from left to right according to the center of the circle , The order from top to bottom is saved in A in .

6、 Option detection

Ideas : about A Each option in the circle , Calculate the coordinates it covers , Then determine the corresponding values of these coordinates in the binary image , Count the number of white dots ,

If the proportion of white is larger , Indicates that this option is selected .

def dots_distance(dot1,dot2):
    # Calculate the distance between two points in two-dimensional space 
    return ((dot1[0]-dot2[0])**2+(dot1[1]-dot2[1])**2)**0.5
def count_dots(center,radius):
    # Enter the center point and radius of the circle , Returns all coordinates within a circle 
    dots = []
    for i in range(-radius,radius+1):
        for j in range(-radius,radius+1):
            dot2 = (center[0]+i,center[1]+j)
            if dots_distance(center,dot2) <= radius:
    return dots
da = []
for i in A:
    dots = count_dots(i[0],i[1])
    all_dots = len(dots)
    whilt_dots = 0
    for j in dots:
        if binary_res[j[1]][j[0]] == 255:
            whilt_dots = whilt_dots+1
    if whilt_dots/all_dots>=0.4:
da = np.array(da)
da = np.reshape(da,(5,5))

 Insert picture description here
In this way, each answer sheet is converted into a two-dimensional array , Next, just do some simple finishing work .

About Python Technology reserve

Learn from good examples Python Whether it's employment or sideline, it's good to make money , But learn to Python Still have a learning plan . Finally, let's share a complete set of Python Learning materials , For those who want to learn Python Let's have a little help !

One 、Python Learning routes in all directions

Python All directions are Python Sort out the common technical points , Form a summary of knowledge points in various fields , The use of it is , You can find the corresponding learning resources according to the above knowledge points , Make sure you learn more comprehensively .

Two 、 Learning software

If a worker wants to do a good job, he must sharpen his tools first . Study Python Common development software is here , It saves you a lot of time .

3、 ... and 、 Getting started video

When we were watching videos to learn , You can't just move your eyes and brain without hands , A more scientific way to learn is to use them after understanding , At this time, the hand training program is very suitable .

Four 、 Practical cases

Optical theory is useless , Learn to knock together , Do it , Can you apply what you have learned to practice , At this time, we can make some practical cases to learn .

5、 ... and 、 Interview information

We learn Python Must be to find a well paid job , The following interview questions are from Ali 、 tencent 、 The latest interview materials of big Internet companies such as byte , And the leader Ali gave an authoritative answer , After brushing this set of interview materials, I believe everyone can find a satisfactory job .

This full version of Python A full set of learning materials has been uploaded CSDN, Friends can scan the bottom of wechat if necessary CSDN The official two-dimensional code is free 【 Guarantee 100% free

copyright notice
author[Program ape Li Xun Tian],Please bring the original link to reprint, thank you.

Random recommended