pythonopencvimage-processingbarcodezxing

How to improve image quality before reading barcode


I am using zxing-cpp library for reading barcode from image.

import cv2
import zxingcpp

img = cv2.imread('test.jpg')
results = zxingcpp.read_barcodes(img)
for result in results:
    print('Found barcode:'
    f'\n Valid:    "{result.valid}"'
        f'\n Text:    "{result.text}"'
        f'\n Format:   {result.format}'
        f'\n Content:  {result.content_type}'
        f'\n Position: {result.position}')
if len(results) == 0:
    print("Could not find any barcode.")

However, this library is unable to scan this simple barcode from image.

How can I processes the image and improve quality of image in order to read the barcode?

I used the answer to this question as a guideline, and was still unsuccessful, therefore I am asking this question and seeking help?


Solution

  • With referencing this question and this question I simply increased brightness and contrast of your image. It seem worked for your image. However, you should know that just because this solution worked for this photo is not a guarantee that it will work for every photo you test.I just followed these steps because I found your photo a little dark and blurry. I think these steps can give you an idea about some of the requirements for barcode detection.

    import cv2
    import zxingcpp
    
    def increase_brightness(img, value=30):
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        h, s, v = cv2.split(hsv)
    
        lim = 255 - value
        v[v > lim] = 255
        v[v <= lim] += value
    
        final_hsv = cv2.merge((h, s, v))
        img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
        return img
    
    def increase_contrast(img, clip_limit=2.0, tile_grid_size=(8,8)):
        lab= cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
        l_channel, a, b = cv2.split(lab)
    
        clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=tile_grid_size)
        cl = clahe.apply(l_channel)
        limg = cv2.merge((cl,a,b))
    
        enhanced_img = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
        return enhanced_img
    
    
    img = cv2.imread('test.jpg')
    cv2.namedWindow("original", cv2.WINDOW_NORMAL)
    cv2.imshow("original", img)
    
    img = increase_brightness(img, 30)
    cv2.namedWindow("brightness_increased", cv2.WINDOW_NORMAL)
    cv2.imshow("brightness_increased", img)
    
    img = increase_contrast(img)
    cv2.namedWindow("contrast_increased", cv2.WINDOW_NORMAL)
    cv2.imshow("contrast_increased", img)
    
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    cv2.namedWindow("grayscale", cv2.WINDOW_NORMAL)
    cv2.imshow("grayscale", img)
    
    results = zxingcpp.read_barcodes(img)
    for result in results:
        print('Found barcode:'
        f'\n Valid:    "{result.valid}"'
            f'\n Text:    "{result.text}"'
            f'\n Format:   {result.format}'
            f'\n Content:  {result.content_type}'
            f'\n Position: {result.position}')
    if len(results) == 0:
        print("Could not find any barcode.")
    
    cv2.waitKey(0)
    

    And the output is:

    Found barcode:
     Valid:    "True"
     Text:    "4607023704821"
     Format:   BarcodeFormat.EAN13
     Content:  ContentType.Text
     Position: 198x549 720x549 720x561 198x561