Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

Python OpenCV 365 day learning plan, enter the graphics realm with eraser. This blog post is the 53rd in the series.

Learned in the previous

From this blog, we will actually complete several small cases, the first one is the identification of bank card number, it is expected to write about 5 blogs to complete this case, let’s cheer up.

The goal of this paper is to obtain a set of figures from 0 to 9 of China Merchants bank card. For the figures below, we need to extract them for subsequent template matching. However, the numbers found in the figure below are not complete. You need to find as many cards as possible and then complete the numbers.

Extract the number associated with the card

Firstly, the relevant extraction operation is carried out on the numbers in the card above, and the grayscale image of the image is loaded to obtain the target area. Simulate the coordinate area on the artboard to facilitate subsequent operations.

The specific code is as follows:

import cv2 as cv
import numpy as np
# Read grayscale image
src = cv.imread("./ka1.jpg".0)

Find the target area of the card number
roi = src[142:168.42:360]
# cv.imshow("roi",roi)
Copy the code

The obtained picture is as follows. It is found that part of content is missing on the right edge, and the coordinates of the target area are fine-tuned.

The modified code is as follows, if you use a picture and eraser inconsistent, pay attention to modify.

Find the target area of the card number
roi = src[142:168.46:364]
cv.imshow("roi",roi)
Copy the code

To eliminate noise, fuzzy convolution operations can be added to test mean blur, median blur, and Gaussian blur effects respectively.

# Fuzzy convolution operation
blur_roi = cv.blur(roi,(5.5))
cv.imshow("blur_roi",blur_roi)

med_roi = cv.medianBlur(roi,5)
cv.imshow("med_roi",med_roi)

gau_roi = cv.GaussianBlur(roi,(7.7),0)
cv.imshow("gau_roi",gau_roi)
Copy the code

To test the effect of different convolution kernels, just choose an appropriate one. I found that when the convolution kernels are (7,7), gaussian blur has a good effect and can be denoised.

The next step is binarization.

# Binarize the target region
ret, thresh = cv.threshold(
    gau_roi, 0.255, cv.THRESH_BINARY | cv.THRESH_OTSU)
cv.imshow("thresh", thresh)
Copy the code

After the binarization, it was found that there were still some points in the white area, which needed to be removed. The corrosion operation in morphology was used here.

# corrosion
kernel = np.ones((3.4), np.uint8)
dst = cv.erode(thresh, kernel=kernel)
Copy the code

After etching, the original digital area is expanded to become obvious. The final image is the effect after etching. You can adjust the convolution kernel by yourself.

# corrosion
kernel = np.ones((3.4), np.uint8)
erode_dst = cv.erode(thresh, kernel=kernel)
cv.imshow("erode_dst", erode_dst)
# inflation
kernel = np.ones((4.4), np.uint8)
dilate_dst = cv.dilate(erode_dst, kernel=kernel)
Copy the code

The following is the outer contour detection. After detection, it is found that there are exactly 16 contours, which corresponds to 16 digital regions.

# Detect contour
Only outer contour is detected
contours, hierarchy = cv.findContours(dilate_dst, cv.RETR_EXTERNAL,  cv.CHAIN_APPROX_SIMPLE)

print(len(contours))
Copy the code

Output the contour area. In order to prevent non-target areas, a basic judgment can be made and the display can be performed only when the width area is greater than 80.

target_list = []
# Contour judgment
for cnt in contours:

    # Contour area
    area = cv.contourArea(cnt)
    print(area)
    if area > 79:
        target_list.append(cnt)

print(len(target_list))
Copy the code

With these parameters, the grayscale image can be cropped, based on the outer rectangle to obtain the target region, I directly made a circular display.

for index, cnt in enumerate(target_list):
    # enclosing rectangle
    x, y, w, h = cv.boundingRect(cnt)
    # Target region acquisition on binarized image
    c_roi = roi[y:y+h, x:x+w]
    # Resize the image
    # big_roi = cv.resize(c_roi, dsize=(0, 0), fx=2, fy=2)
    # big_roi = cv.resize(c_roi, dsize=(0, 0))
    cv.imshow("big_roi"+str(index), c_roi)
    # cv.imwrite(f"./numbers/ka_{index}.png", big_roi)
Copy the code

Next, you can enlarge the picture and save it to get the following picture list. So far, you have obtained the numbers 1, 4, 6 and 8. Now you can switch to another card to obtain other numbers.

big_roi = cv.resize(c_roi, dsize=(42.66))
# cv.imshow("c_roi"+str(index), c_roi)
cv.imwrite(f"./numbers/ka1_{index}.png", big_roi)
Copy the code

New image attention to adjust the target area, to obtain the material, has been obtained 1, 2, 4, 5, 6, 7, 8 several numbers

Iterate over this method until 0~9 digits are complete, and after finding all digits, binarize all files in the folder.

import cv2 as cv
import os

def walk_file(file) :
    for root, dirs, files in os.walk(file):
        for f in files:
            file = os.path.join(root, f)
            # Read grayscale image
            basename = os.path.basename(file)
            filename = basename.split(".") [0]
            src = cv.imread(file, 0)
            ret, thresh = cv.threshold(src, 0.255, cv.THRESH_BINARY | cv.THRESH_OTSU)
            # cv.imshow("thresh", thresh)
            cv.imwrite(f"./numbers/001_{filename}_bit.png", thresh)
            cv.waitKey()
            cv.destroyAllWindows()

if __name__ == "__main__":
    walk_file("./numbers")
Copy the code

After binarization, clear numbers can be selected. If there is any unclear number, you can find resources to extract it. There are too many 8 in the bank.

After the final adjustment of the eraser, the result is something like this, and the first step of credit card number identification is ready.

Eraser section

I also encountered some problems today, the most difficult problem is that the colors are similar, so I can’t extract the numbers in front. I hope you got something out of your hour today, and we’ll see you in our next blog