Development of the ocr part of AOI
Samo Penic
2018-11-16 511c2e7452a37fd32e7e7e1b83d46277ea57b6e3
Ocr.py
@@ -4,10 +4,7 @@
import math
class Paper():
class Paper:
   def __init__(self, filename=None):
      self.filename=filename
      self.invalid=None
@@ -18,7 +15,6 @@
         self.loadImage(filename)
         self.runOcr()
   def loadImage(self, filename, rgbchannel=0):
      self.img=cv2.imread(filename,rgbchannel)
      if self.img is None:
@@ -27,7 +23,7 @@
         return
      self.imgHeight, self.imgWidth = self.img.shape[0:2]
   def saveImage(self, filename='debug_image.png'):
    def saveImage(self, filename="debug_image.png"):
      cv2.imwrite(filename, self.img)
   def runOcr(self):
@@ -63,29 +59,34 @@
      ypos=d[0].rect.top
      #check if image is rotated wrongly
      if xpos>self.imgHeight/2.0 and ypost>self.imgWidth/2.0:
         self.rotate(180)
            self.rotateAngle(180)
   def rotateAngle(self,angle=0):
      rot_mat = cv2.getRotationMatrix2D((self.imgHeight/2, self.imgWidth/2), angle, 1.0)
      result = cv2.warpAffine(self.img,
        rot_mat = cv2.getRotationMatrix2D(
            (self.imgHeight / 2, self.imgWidth / 2), angle, 1.0
        )
        result = cv2.warpAffine(
            self.img,
                        rot_mat,
                        (self.imgHeight, self.imgWidth),
                        flags=cv2.INTER_CUBIC,
                        borderMode=cv2.BORDER_CONSTANT,
                        borderValue=(255, 255, 255))
            borderValue=(255, 255, 255),
        )
      self.img=result
      self.imgHeight, self.imgWidth = self.img.shape[0:2]
   #todo, make better tresholding
   def imgTreshold(self):
      (self.thresh, self.bwimg) = cv2.threshold(self.img, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
   
    def imgTreshold(self):
        (self.thresh, self.bwimg) = cv2.threshold(
            self.img, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU
        )
   def getSkewAngle(self):
      neg = 255 - self.bwimg  # get negative image
      cv2.imwrite('debug_1.png', neg)
        cv2.imwrite("debug_1.png", neg)
      angle_counter = 0 # number of angles
      angle = 0.0 # collects sum of angles
@@ -104,16 +105,17 @@
      # the skew is calculated of the mean of the total angles, #try block helps with division by zero.
      try:
         skew = np.rad2deg(angle / angle_counter) #the 1.2 factor is just experimental....
            skew = np.rad2deg(
                angle / angle_counter
            )  # the 1.2 factor is just experimental....
      except:
         skew=0
      cv2.imwrite('debug_2.png',cimg)
        cv2.imwrite("debug_2.png", cimg)
      return skew
   def locateUpMarkers(self, threshold=0.8, height=200):
      template = cv2.imread('template.png',0)
    def locateUpMarkers(self, threshold=0.85, height=200):
        template = cv2.imread("template.png", 0)
      w, h = template.shape[::-1]
      crop_img = self.img[0:height, :]
      res = cv2.matchTemplate(crop_img,template,cv2.TM_CCOEFF_NORMED)
@@ -122,13 +124,18 @@
      #remove false matching of the squares in qr code
      loc_filtered_x=[]
      loc_filtered_y=[]
        if len(loc[0]) == 0:
            min_y = -1
        else:
      min_y=np.min(loc[0])
      for pt in zip(*loc[::-1]):
         if(pt[1]<min_y+20):
                if pt[1] < min_y + 20:
            loc_filtered_y.append(pt[1])
            loc_filtered_x.append(pt[0])
      #order by x coordinate
      loc_filtered_x,loc_filtered_y = zip(*sorted(zip(loc_filtered_x, loc_filtered_y)))
            loc_filtered_x, loc_filtered_y = zip(
                *sorted(zip(loc_filtered_x, loc_filtered_y))
            )
      #loc=[loc_filtered_y,loc_filtered_x]
      #remove duplicates
      a=np.diff(loc_filtered_x)>40
@@ -139,14 +146,13 @@
      for pt in zip(*loc[::-1]):
         cv2.rectangle(cimg, pt, (pt[0] + w, pt[1] + h), (0,255,255), 2)
      cv2.imwrite('debug_3.png',cimg)
        cv2.imwrite("debug_3.png", cimg)
      self.xMarkerLocations=loc
      return loc
   def locateRightMarkers(self, threshold=0.8, width=200):
      template = cv2.imread('template.png',0)
    def locateRightMarkers(self, threshold=0.85, width=200):
        template = cv2.imread("template.png", 0)
      w, h = template.shape[::-1]
      crop_img = self.img[:, -width:]
      res = cv2.matchTemplate(crop_img,template,cv2.TM_CCOEFF_NORMED)
@@ -155,13 +161,18 @@
      #remove false matching of the squares in qr code
      loc_filtered_x=[]
      loc_filtered_y=[]
        if len(loc[1]) == 0:
            min_x = -1
        else:
      max_x=np.max(loc[1])
      for pt in zip(*loc[::-1]):
         if(pt[1]>max_x-20):
                if pt[1] > max_x - 20:
            loc_filtered_y.append(pt[1])
            loc_filtered_x.append(pt[0])
      #order by y coordinate
      loc_filtered_y,loc_filtered_x = zip(*sorted(zip(loc_filtered_y, loc_filtered_x)))
            loc_filtered_y, loc_filtered_x = zip(
                *sorted(zip(loc_filtered_y, loc_filtered_x))
            )
      #loc=[loc_filtered_y,loc_filtered_x]
      #remove duplicates
      a=np.diff(loc_filtered_y)>40
@@ -172,12 +183,10 @@
      for pt in zip(*loc[::-1]):
         cv2.rectangle(cimg, pt, (pt[0] + w, pt[1] + h), (0,255,255), 2)
      cv2.imwrite('debug_4.png',cimg)
        cv2.imwrite("debug_4.png", cimg)
      self.yMarkerLocations=[loc[0], loc[1]+self.imgWidth-width]
      return self.yMarkerLocations
   def generateAnswerMatrix(self):
      self.locateUpMarkers()
@@ -193,9 +202,11 @@
      for y in self.yMarkerLocations[0]:
         oneline=[]
         for x in self.xMarkerLocations[1]:
            roi=self.bwimg[ y-roiyoff:y+int(roiheight-roiyoff),x-roixoff:x+int(roiwidth-roixoff)]
                roi = self.bwimg[
                    y - roiyoff : y + int(roiheight - roiyoff),
                    x - roixoff : x + int(roiwidth - roixoff),
                ]
            #cv2.imwrite('ans_x'+str(x)+'_y_'+str(y)+'.png',roi)
            black=totpx-cv2.countNonZero(roi)
            oneline.append(black/totpx)
         self.answerMatrix.append(oneline)