Ini ide. Kami memecah masalah ini menjadi beberapa langkah:
Tentukan rata-rata area kontur persegi panjang. Kami ambang lalu menemukan kontur dan filter menggunakan area persegi panjang pembatas dari kontur. Alasan kami melakukan ini adalah karena pengamatan bahwa setiap karakter khas hanya akan begitu besar sedangkan kebisingan besar akan menjangkau area persegi panjang yang lebih besar. Kami kemudian menentukan area rata-rata.
Hapus kontur outlier besar. Kami beralih melalui kontur lagi dan menghapus kontur besar jika mereka 5x
lebih besar dari area kontur rata-rata dengan mengisi kontur. Alih-alih menggunakan area ambang tetap, kami menggunakan ambang dinamis ini untuk ketahanan lebih.
Dilatasi dengan kernel vertikal untuk menghubungkan karakter . Idenya adalah memanfaatkan pengamatan bahwa karakter disejajarkan dalam kolom. Dengan melebarkan dengan kernel vertikal kami menghubungkan teks bersama sehingga noise tidak akan dimasukkan dalam kontur gabungan ini.
Hapus kebisingan kecil . Sekarang setelah teks disimpan, kami menemukan kontur dan menghapus kontur yang lebih kecil dari 4x
area kontur rata-rata.
Bitwise-dan untuk merekonstruksi gambar . Karena kami hanya menginginkan kontur untuk tetap berada di topeng kami, kami bitwise-dan untuk melestarikan teks dan mendapatkan hasil kami.
Berikut visualisasi prosesnya:
Kami menetapkan ambang Otsu untuk mendapatkan gambar biner kemudian menemukan kontur untuk menentukan rata-rata area kontur persegi panjang. Dari sini kami menghapus kontur outlier besar yang disorot dengan warna hijau dengan mengisi kontur
Selanjutnya kita membangun kernel vertikal dan melebar untuk menghubungkan karakter. Langkah ini menghubungkan semua teks yang diinginkan untuk menyimpan dan mengisolasi suara menjadi gumpalan individual.
Sekarang kami menemukan kontur dan filter menggunakan area kontur untuk menghilangkan kebisingan kecil
Berikut adalah semua partikel kebisingan yang dihapus yang disorot dengan warna hijau
Hasil
Kode
import cv2
# Load image, grayscale, and Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Determine average contour area
average_area = []
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
area = w * h
average_area.append(area)
average = sum(average_area) / len(average_area)
# Remove large lines if contour area is 5x bigger then average contour area
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
area = w * h
if area > average * 5:
cv2.drawContours(thresh, [c], -1, (0,0,0), -1)
# Dilate with vertical kernel to connect characters
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,5))
dilate = cv2.dilate(thresh, kernel, iterations=3)
# Remove small noise if contour area is smaller than 4x average
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < average * 4:
cv2.drawContours(dilate, [c], -1, (0,0,0), -1)
# Bitwise mask with input image
result = cv2.bitwise_and(image, image, mask=dilate)
result[dilate==0] = (255,255,255)
cv2.imshow('result', result)
cv2.imshow('dilate', dilate)
cv2.imshow('thresh', thresh)
cv2.waitKey()
Catatan: Pemrosesan gambar tradisional terbatas pada ambang, operasi morfologis, dan pemfilteran kontur (perkiraan kontur, area, rasio aspek, atau deteksi gumpalan). Karena gambar input dapat bervariasi berdasarkan ukuran teks karakter, menemukan solusi tunggal cukup sulit. Anda mungkin ingin melihat pelatihan classifier Anda sendiri dengan pembelajaran mesin / mendalam untuk solusi yang dinamis.