pythonopencvimage-processingbackground-processnoise-reduction

Detect textured background for contrasted images


I have two types of images, and they were both contrasted.

Type 1: (white and clean background)

Type 1

Type 2: (some gray texture in background)

enter image description here

I could apply Gaussian blur and Thresholding to process the type 2 image to adjust it to the white background like type 1 as follow code:

type2_img = cv2.imread(type2.png)
# convert to grayscale
gray = cv2.cvtColor(type2_img , cv2.COLOR_BGR2GRAY)
# threshold the image using Otsu's thresholding
thresh = cv2.threshold(gray.copy(), 0, 255, cv2.THRESH_OTSU)[1]
# convert back to RGB
type2_img = cv2.cvtColor(thresh,cv2.COLOR_GRAY2RGB)

And, I could get the following result enter image description here:

However, I do not wish to apply the same method for type 1 images, since it is already satisfied condition.

So, are there any image processing methods within OpenCV that can differentiate type 2 images from type 1?


Solution

  • The type 1 image you provided is grayscale and not completely black & white image. Yet the last threshold output image is black and white.

    Based on your question my understanding is both of these should as classified as type 1 and the type 2 image example should classified as type 2.

    If it was the case that type 1 was always black and white you could count the number of 0's and 1's in image and check if their sum equaled to total pixel count of image.

    An option here is to classify two types of image without modifying images is to use the percentage of black and white pixels of image histogram.

    Code

    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    from skimage import exposure
    
    #img_path = r'hist_imgs/1.png'
    #img_path = r'hist_imgs/2.png'
    img_path = r'hist_imgs/3.png'
    
    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    cv2.imshow('Image', img)
    
    img_pixel_count = img.shape[0] * img.shape[1]
    print(img.shape)
    print(img_pixel_count)
    
    h = np.array(exposure.histogram(img, nbins=256))
    
    bw_count = h[0][0] + h[0][255]
    other_count = img_pixel_count - bw_count
    
    print('BW PIXEL COUNT: ',  bw_count)
    print('OTHER PIXEL COUNT: ',  other_count)
    
    bw_percentage = (bw_count * 100.0) / img_pixel_count
    other_percentage = (other_count * 100.0) / img_pixel_count
    
    print('BW PIXEL PERCENTAGE: ',  bw_percentage)
    print('OTHER PIXEL PERCENTAGE: ',  other_percentage)
    
    differentiate_threshold = 3.0
    if other_percentage > differentiate_threshold:
        print('TYPE 2: GRAYSCALE')
    else:
        print('TYPE 1: BLACK AND WHITE')
    
    plt.hist(img.ravel(), 256, [0, 256])
    plt.title('Histogram')
    plt.show()
    

    Input Images

    Image 1:

    enter image description here

    Image 2:

    enter image description here

    Image 3:

    enter image description here

    Code Output

    Image 1:

    (154, 74)
    11396
    BW PIXEL COUNT:  11079
    OTHER PIXEL COUNT:  317
    BW PIXEL PERCENTAGE:  97.21832221832221
    OTHER PIXEL PERCENTAGE:  2.781677781677782
    TYPE 1: BLACK AND WHITE
    

    Image 2:

    (38, 79)
    3002
    BW PIXEL COUNT:  1543
    OTHER PIXEL COUNT:  1459
    BW PIXEL PERCENTAGE:  51.39906728847435
    OTHER PIXEL PERCENTAGE:  48.60093271152565
    TYPE 2: GRAYSCALE
    

    Image 3:

    (38, 79)
    3002
    BW PIXEL COUNT:  3002
    OTHER PIXEL COUNT:  0
    BW PIXEL PERCENTAGE:  100.0
    OTHER PIXEL PERCENTAGE:  0.0
    TYPE 1: BLACK AND WHITE