Binarization method of super large image
分块处理超大图像的二值化问题
(1) 全局阈值处理
(2) 局部阈值(效果更好)
空白区域过滤
先缩放进行二值化,然后还原大小
The binarization problem of processing super large images in blocks
import cv2 as cv
import numpy as np
def big_image_binary(image):
print(image.shape) #图像大小
ch, cw = 255, 255 #每个小块的高和宽
h, w = image.shape[:2]#整个图像高,宽
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) #进行二值化必须先转成灰度图
for row in range(0, h, ch):#遍历每一小块高
for col in range(0, w, cw):#遍历每一块宽
roi = gray[row:row+ch, col:col+cw] #获取分块
mean, std = cv.meanStdDev(roi)
print("the picture mean:%s, std:%s" % (mean, std)) #打印小块均值,方差
# ret, dst = cv.threshold(roi, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) #全局阈值
dst = cv.adaptiveThreshold(roi, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 127, 10) #局部阈值
gray[row:row+ch, col:col+cw] = dst #对每个个块进行二值化处理
cv.imwrite("binary2.jpg",gray)
src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/xiannvbang.jpg")
big_image_binary(src)
cv.waitKey(0)
cv.destroyAllWindows()
Running screenshot:
Each small block uses a global threshold. Due to the influence of noise, the shadow of the red square will appear first, and the effect is relatively poor
Local threshold
dst = cv.adaptiveThreshold(roi, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 127, 10)
Code screenshot:
The effect of the local threshold is better, because there is a C value in the local threshold, which can remove some noise
White space filtering
import cv2 as cv
import numpy as np
def big_image_binary(image):
ch, cw = 200, 200 #分块每个块的大小
h, w = image.shape[:2]
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) #转成灰度图
for row in range(0, h, ch):
for col in range(0, w, cw):
roi = gray[row:row+ch, col:col+cw]
mean, std = cv.meanStdDev(roi)
print("the picture mean:%s, std:%s" % (mean, std))
if std < 10 and mean > 80: #如果标准差小于10或者均值大于80,将此处的值设为255
gray[row:row + ch, col:col + cw] = 255
else:
ret, dst = cv.threshold(roi, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) #全局阈值
gray[row:row+ch, col:col+cw] = dst #对每个个块进行二值化处理
cv.imshow("binary", gray)
src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/xiannvbang.jpg")
cv.namedWindow("input_image", cv.WINDOW_AUTOSIZE)
cv.imshow("input_image", src)
big_image_binary(src)
cv.waitKey(0)
cv.destroyAllWindows()
Zoom first, then binarize
Image zoom function cv.resize
resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None)
src: input, the original image, that is, the image to be resized;
dst: output, the changed image. This image has the same content as the original image, but the size is different from the original image;
dsize: the size of the output image. If this parameter is not 0, it means that the original image is scaled to the size specified by this Size(width, height); if this parameter is 0, then the following formula is used to calculate:
dsize = Size(round(fxsrc.cols), round(fysrc.rows))
Among them, fx and fy are the two parameters to be mentioned below, which are the zoom ratios of the image width and height directions.
fx: the zoom ratio in the width direction, if it is 0, then it will be calculated according to (double)dsize.width/src.cols;
fy: the zoom ratio in the height direction, if it is 0, then it will be calculated according to ( double)dsize.height/src.rows;
interpolation: This is the way to specify the interpolation. After the image is scaled, the pixels must be recalculated. This parameter is used to specify the way to recalculate the pixels. There are the following:
INTER_NEAREST-nearest neighbor interpolation
INTER_LINEAR-bilinear interpolation, if you do not specify the last parameter, this method is used by default
INTER_AREA-resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
INTER_CUBIC-4x4 pixel area in the neighborhood Cubic interpolation
INTER_LANCZOS4-Lanczos interpolation in the neighborhood of 8x8 pixels
numpy knowledge supplement
np.mean() 返回数组元素的平均值
np.std() 返回数组元素的标准差