Search code examples
pythonopencvleptonica

how can I get the same result of leptonica's pixReduceRankBinary2 and pixCloseBrick on openCV?


I am translating a go program that uses leptonica library to a python script that uses openCV, and I cant find a way to translate the following:

img = pixReduceRankBinary2(img, 2, NULL);
img = pixReduceRankBinary2(img, 2, NULL);
img = pixCloseBrick(NULL, img, 2, 3);

is there an implementation of those functions in openCV?


Solution

  • Here is one way to do that using Python/OpenCV/Skimage. Simply read the image and ensure it is binary. The use Skimage downscale_local_mean to downsample by 2 using 2x2 neighborhoods producing a factor of two smaller image whose values are the means of the 2x2 neighborhoods. Then threshold again in 25% increments to correspond to leptonica counts for their pixReduceRankBinary2 function.

    Input (rice grains):

    enter image description here

    import cv2
    import numpy as np
    import skimage.transform
    
    # read image
    img = cv2.imread('rice_bw.png')
    
    # convert to gray
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # threshold to binary
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
    
    # decimate by factor of 2 to mean values in 2x2 regions
    decimate = skimage.transform.downscale_local_mean(thresh, (2,2))
    
    # set count to 1,2,3 or 4
    count=2
    
    # convert count to percent of 255 in increments of 25%
    count_thresh = 255 * (25/100) * count
    
    # threshold again
    result = cv2.threshold(decimate, count_thresh, 255, cv2.THRESH_BINARY)[1]
    
    # write result to disk
    cv2.imwrite("rice_bw_binary_decimate.png", result)
    
    # show result
    cv2.imshow("result", result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    Result for count=2:

    enter image description here