Saya mendeteksi teks dari berbagai gambar paspor dengan OpenCV. Tugasnya adalah untuk mendapatkan teks yang dipotong pada paspor seperti Nama, DOB, Kebangsaan, dll. Kode saat ini diberikan di bawah ini:

image = cv2.imread(image) # read image
image = imutils.resize(image, height=600)

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (3, 3), 0)

rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (13, 5))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 21))
blackhat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, rectKernel)

gradX = cv2.Sobel(blackhat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)
gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
gradX = (255 * ((gradX - minVal) / (maxVal - minVal))).astype("uint8")

gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

if do_erosion: # do erosion if flag is True only
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)
    thresh = cv2.erode(thresh, None, iterations=4)
p = int(image.shape[1] * 0.05)
thresh[:, 0:p] = 0
thresh[:, image.shape[1] - p:] = 0   # thresholded image shown below

cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)   # finding contours from threshold image
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
rois=[]
# loop over the contours
for c in cnts:
    # compute the bounding box of the contour and use the contour to
    # compute the aspect ratio and coverage ratio of the bounding box
    # width to the width of the image
    (x, y, w, h) = cv2.boundingRect(c)
    ar = w / float(h)
    crWidth = w / float(gray.shape[1])
    # check to see if the aspect ratio and coverage width are within
    # acceptable criteria
    
    if ar > 2 and crWidth > 0.05:
        # pad the bounding box since we applied erosions and now need
        # to re-grow it
        pX = int((x + w) * 0.03)
        pY = int((y + h) * 0.03)
        (x, y) = (x - pX, y - pY)
        (w, h) = (w + (pX * 2), h + (pY * 2))
        # extract the ROI from the image and draw a bounding box
        # surrounding the MRZ
        roi = original[y:y + h, x:x + w].copy()  # interested in finding all ROIs having text
        rois.append(roi)
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

Saya mendeteksi beberapa nilai tekstual dengan benar tetapi solusinya tidak umum. Terkadang hanya mengekstrak tahun DOB tetapi bukan tanggal penuh (terkadang mendeteksi bulan dan hari juga tetapi tidak dalam ROI yang sama). Gambar asli dan ambang ditunjukkan di bawah ini:

original image

threshold image

ROIs detected on image,

Seperti yang Anda lihat, di "gambar ROI yang ditemukan" beberapa ROI tidak terdeteksi pada gambar yang sama seperti DOB dan tanggal kedaluwarsa. Bantuan apa pun dalam mengekstrak semua wilayah teks dari paspor akan sangat dihargai. Terima kasih!

2
Asim 20 November 2020, 11:19

1 menjawab

Jawaban Terbaik

Anda perlu mengubah ambang Rasio Aspek dan Rasio Cakupan untuk mendapatkan semua kotak pembatas yang diinginkan. Ketika saya menjalankan kode Anda, untuk 05, nilai ar adalah 1.541 dan nilai crWidth adalah 0.03. Karena nilai-nilai ini kurang dari ambang batas yang Anda tentukan, nilai-nilai tersebut difilter. Inilah sebabnya mengapa beberapa kata tidak memiliki kotak pembatas di gambar akhir.

Namun, karena Anda ingin mendapatkan seluruh DOB dalam satu kotak pembatas, tepat sebelum baris thresh[:, 0:p] = 0, Anda dapat menerapkan operasi dilatasi:
thresh = cv2.morphologyEx(thresh, cv2.MORPH_DILATE, np.ones((1, 30), np.uint8)).

Ini akan melebarkan piksel dan menggabungkan gumpalan yang ada di dekatnya secara horizontal. Gambar yang dihasilkan setelah preprocessing adalah sebagai berikut - masukkan deskripsi gambar di sinimasukkan deskripsi gambar di sini

GaneshTata 20 November 2020, 09:48