0

I have a real problem, I hope you will help me) I'm trying to detect this barcode with Python + cv2 module:

This works:

import numpy as np
import cv2
import argparse
import glob
import os

# construct the argument parse and parse the arguments
#ap = argparse.ArgumentParser()
#ap.add_argument("-i", "--image", required = False, help = "path to the image file")
#args = vars(ap.parse_args())

for filename in glob.iglob('/media/smirnovakatrin/7213B7596212C502/Machine_learning/*.jpg'):
     #print('/foobar/%s' % filename)
     #image = cv2.imread(args["image"])
     image = cv2.imread(filename)

     # convert the image to grayscale
     gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        # compute the Scharr gradient magnitude representation of the images
     # in both the x and y direction
     gradX = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 1, dy = 0, ksize = -1)
     gradY = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 0, dy = 1, ksize = -1)

     # subtract the y-gradient from the x-gradient
     gradient = cv2.subtract(gradX, gradY)
     gradient = cv2.convertScaleAbs(gradient)

     # blur and threshold the image
     blurred = cv2.blur(gradient, (3, 3))
     (_, thresh) = cv2.threshold(blurred, 230, 280, cv2.THRESH_BINARY)

     # construct a closing kernel and apply it to the thresholded image
     kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
     closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

     # perform a series of erosions and dilations
     closed = cv2.erode(closed, None, iterations = 7)
     closed = cv2.dilate(closed, None, iterations = 2)

     #cv2.imshow("Image", closed)
     #cv2.waitKey(0)

     # find the contours in the thresholded image
     (im2,cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,
     cv2.CHAIN_APPROX_SIMPLE)

     # otherwise, sort the contours by area and compute the rotated
     # bounding box of the largest contour
     c = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
     rect = cv2.minAreaRect(c)
     box = np.int0(cv2.boxPoints(rect))

     cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
     cv2.imshow("Image", image)
     cv2.waitKey(0)
     image_file = '/media/smirnovakatrin/7213B7596212C502/Machine_learning/' + os.path.basename(filename);
     cv2.imwrite(image_file, image)

But when I have done this code, 4 corners are not correct (barcode isn't defined in a right way). Maybe I need to search a solution by CNN or zbar? I change parameters 230 and 280 in cv2.threshold(blurred, 230, 280, cv2.THRESH_BINARY), initially 50 and 250, but this doesn't give a result. I have 10000 photos with barcode (different price tags photographed at different angles with different brightness) and it's impossible to set up each photo separately.

Siddharth Das
  • 1,057
  • 1
  • 15
  • 33
Katrin
  • 11
  • 1
  • 5
  • @OlivierMelançon This is very similar to that but Katrin, do you have a reason not to use that solution or zbar? – Zev Jun 03 '18 at 18:26
  • 1
    @Olivier Melançon yes, I have read this item. But this code makes worse result. I try to set up this algorithm. Maybe I do something wrong. I need to identify a big quantity of photos. Do I need to set up this code for each photo separately? – Katrin Jun 03 '18 at 18:38
  • MinAreaRect is trying to find the smallest rectangle to put around all the points but because the contour is way off and includes points you don't want, it isn't able to create a rectangle where you want. Because this solution seems far from working you may be best off trying more with zbar. I'd spend more time with https://stackoverflow.com/questions/50497945/how-to-reliably-detect-a-barcodes-4-corners as zbar is pretty good at this task and there are some good suggestions for articles in the question. – Zev Jun 03 '18 at 18:51
  • @Katrin i'm not an expert on that matter, so since this other question did not help, I rétracter my close vote – Olivier Melançon Jun 03 '18 at 19:30

0 Answers0