简体   繁体   English

OpenCV 中的图像阈值处理

[英]Image thresholding in OpenCV

I have following image ,which is scanned image of A4 paper.What I need to do is to render individual characters from scanned image in to 28*28 or 32*32 image.我有以下图像,它是 A4 纸的扫描图像。我需要做的是将扫描图像中的单个字符渲染为 28*28 或 32*32 图像。 I am doing it for dataset generation for Devanagari OCR.我正在为天城文 OCR 生成数据集。 I applied simple threshing that doesn't help me.But when I applied adaptive threshing the result is not like expected.我应用了对我没有帮助的简单脱粒。但是当我应用自适应脱粒时,结果并不像预期的那样。 这是我输入的扫描图像

After performing greyscaling and thresholding I get following thresholded image执行灰度和阈值处理后,我得到以下阈值图像脱粒图像

My Final individual character image rendered are like我渲染的最终个人角色图像就像在此处输入图片说明

But my expected images(28*28) are was like ..但我预期的图像(28 * 28)就像.. 在此处输入图片说明

My source code is:我的源代码是:

# grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# cv2.imshow('gray', gray)

# binary
#simple threshing
#ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
#cv2.imshow('threshold', thresh)
# adaptive threshing
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV,11,6)
cv2.imshow('threshold', thresh)

# dilation
kernel = np.ones((10, 1), np.uint8)
img_dilation = cv2.dilate(thresh, kernel, iterations=1)

# find contours
# cv2.findCountours() function changed from OpenCV3 to OpenCV4: now it have only two parameters instead of 3
cv2MajorVersion = cv2.__version__.split(".")[0]
# check for contours on thresh
if int(cv2MajorVersion) >= 4:
    ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
else:
    im2, ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, 
cv2.CHAIN_APPROX_SIMPLE)

# sort contours
sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0])

for i, ctr in enumerate(sorted_ctrs):
    # Get bounding box
    x, y, w, h = cv2.boundingRect(ctr)

    # Getting ROI
    # roi = image[y:y + h, x:x + w]
    roi = thresh[y:y + h, x:x + w]

    # resizing
    resize = cv2.resize(roi, (28, 28))

    if w > 15 and h > 15:
        cv2.imwrite(str(i) + str(time.time()) + '{}.png'.format(i), resize)

Please suggest me how to extract individual character in black and white 28*28 image for dataset collection.If you have any idea about dataset generation,It will be highly appriciated.请建议我如何提取黑白 28*28 图像中的单个字符以进行数据集收集。如果您对数据集生成有任何想法,这将非常受欢迎。

The problem is how you are finding contours.问题是你如何找到轮廓。

An input parameter which requires Contour Retrieval Modes in a cv.findContours() (available options are)cv.findContours()需要Contour Retrieval Modes的输入参数(可用选项是)

cv.RETR_LIST, cv.RETR_TREE, cv.RETR_CCOMP, cv.RETR_EXTERNAL cv.RETR_LIST, cv.RETR_TREE, cv.RETR_CCOMP, cv.RETR_EXTERNAL

cv.RETR_EXTERNAL only finds the outer most member in the nested contours family. cv.RETR_EXTERNAL只找到嵌套轮廓系列中最外面的成员。 More can be found here这里可以找到更多

So with your code at所以用你的代码

if int(cv2MajorVersion) >= 4:
    ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

When drawing rectangles on contours shows在轮廓上绘制矩形时显示嵌套轮廓中只有父轮廓

On changing contours retrieval code using cv2.RETR_LIST使用cv2.RETR_LIST更改轮廓检索代码

if int(cv2MajorVersion) >= 4:
    ctrs, hier = cv2.findContours(thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

When drawing rectangles on contours shows在轮廓上绘制矩形时显示不考虑层次结构的所有轮廓

Later on, using your logic with the restricted size of contours if w > 15 and h > 15: (on changing this dimension as needed) you can get you the images of characters稍后, if w > 15 and h > 15: ,则使用具有受限轮廓大小的逻辑if w > 15 and h > 15:根据需要更改此尺寸)您可以获得字符图像

Edited已编辑

if (w > 20 and h > 20) and (w < 130 and h < 120):
   cv2.imwrite(str(i) + str(time.time()) + '{}.png'.format(i), resize)

期望输出

This works for me, gives nice pictures, black and white:这对我有用,给出了漂亮的黑白照片:

#!/usr/bin/env python

import cv2

counter = 0
img = cv2.imread( 'Downloads/dewangari.jpg' )
print img.shape #(2338, 1700, 3)
img = img[77:1942,91:1517]
img.shape   # (1426, 1623, 3)

_, img = cv2.threshold( img[:,:,2], 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

x_size = img.shape[0] / 15
y_size = img.shape[1] / 8

for i in range(8) :
    for j in range(15) :
        cell = img[j*x_size+7:(j+1)*x_size-7,i*y_size+7:(i+1)*y_size-7]
        cv2.imshow( 'frame', cell )

        cell = (255 - cell)   # this inverts the image

        cv2.imwrite( 'image_%03d.png' % counter, cell)
        counter += 1  # this saves the image

        cv2.waitKey(0)

cv2.destroyAllWindows()

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

and so on ....等等 ....

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM