Сегментация символов в Python с OpenCV, возвращающим связанные символы и случайные строки - PullRequest
0 голосов
/ 12 февраля 2020

Я пытаюсь сегментировать символы из изображений слова, которое выглядит следующим образом: image of word

Слова были выделены с помощью EAST из этого изображения естественного текста a natural text image

Мой алгоритм сегментации возвращает в основном хорошие изображения символов, но некоторые возвращаются просто тонкими линиями, а некоторые возвращаются все еще подключенными. Я сегментирую символы и помещаю их на белый фон 30х30.

def charSegment(image):
    image=cv2.imread(image,0)
    orig=image
    kernel=np.ones((5,10),np.uint8)
    image=cv2.addWeighted(image, 1.5,np.zeros(image.shape, image.dtype), 0, 0)
    blurred=cv2.GaussianBlur(image, (3,3),0)
    dilated=cv2.dilate(blurred,kernel,iterations=2)
    x,thresholded=cv2.threshold(image,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    thresholded=(255-thresholded)
    contours,hierarchy=cv2.findContours(thresholded.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    sortedConts=sorted(contours,key=lambda ctr: cv2.boundingRect(ctr)[0]) 
    charlist=[]
    for i, ctr in enumerate(sortedConts):
        x,y,w,h=cv2.boundingRect(ctr)
        if w>=6 or h>=8:
            charlist.append(orig[y:y+h,x:x+w])
    return charlist

И это моя подпрограмма для подгонки символов:

def fitImage(image):
    null,thresholded=cv2.threshold(image,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    image=Image.fromarray(thresholded)
    x,y=image.size
    while x>30 or y>30:
        x,y=(i/1.05 for i in (x,y))
    while x<30 or y<30:
        if any((i*1.05>30 for i in (x,y))):
            break
        else:
            x,y=(i*1.05 for i in (x,y))
    x,y=(int(floor(i)) for i in (x,y))
    image=image.resize((x,y),Image.LANCZOS).convert("L")
    img=Image.new("L",(30,30),color=255)
    offset=((30-x)//2,(30-y)//2)
    img.paste(image,offset) 
    img.filter(ImageFilter.SMOOTH_MORE)
    return np.array(img)

Две подпрограммы называются так:

for x in imagesList:
    x.save("tmp/temp.png")
    characterList.append([imagePrep.fitImage(x) for x in imagePrep.charSegment("tmp/temp.png")])

Этот подход возвращает в основном правильные изображения символов, такие как: correct image of an L или correct image of a W

, но также возвращает множество случайных строк : a random line another random line

, а также связанные символы: an image of CA an image of EP

Можно ли как-нибудь устранить эти ошибки? Спасибо!

...