乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      ocr圖像預處理...

       黃爸爸好 2021-03-30

      說明:文字方向校正(fft方式和放射變換方式)參考了網(wǎng)上的代碼,只做了少量修改
      只針對醫(yī)療影像圖像,自然場景下的另說
      因為處理的圖像都很大很大,居然有11000*12000這種分辨率的,有90M大小,我也是醉了,絕大部分都是6000左右分辨率的圖像,這種圖像直接送到CTPN里的話,效果不是太好,太大了 而且效率感人,所以必須做一下預處理。大部分的X光圖像很簡單,直接縮放送CTPN即可,而CT和MRI圖像雖然一張上有很多小圖像,但好在要么有虛線分割要么中間都會留有空白的地方,于是就可以利用直線檢測和投影檢測來把圖片分割成若干小圖像了。(吐槽一下之前老外寫的代碼,不管三七二十一把所有圖像都是分成上下兩部分,然后上下再各分成上下兩部分,四個部分再分別循環(huán)他的N個算法,搞的整個系統(tǒng)70%以上的資源都在跑OCR,一張很簡單的圖片最低也要幾分鐘才能出結(jié)果,復雜一點的都是10幾分鐘 真想知道這是怎么過驗收的!)

      1. 圖像分割,思想很簡單 有虛線的直接做直線檢測,有空白的做X、Y軸的投影,都沒有的就是X光圖像了,直接把整張圖像當做ROI送CTPN
      def _img_split_with_hough(img, min=100, max=220):
          """
          :param img: 讀入的二值化圖
          :param min: 邊緣檢測閾值
          :param max: 邊緣檢測閾值
          :return: 水平和垂直線的坐標集合
          """
          h = img.shape[0]
          w = img.shape[1]
          edges = cv2.Canny(img, min, max)
          lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 30, minLineLength=100, maxLineGap=10)
          lines1 = lines[:, 0, :]
          h_line = []
          v_line = []
          for x1, y1, x2, y2 in lines1[:]:
              if y2 == y1:
                  flag = False
                  for element in h_line:
                      if abs(element[1] - y1) < 10:
                          flag = True
                          break
                  if flag == False and abs(x1 - x2) > w * 0.5:
                      h_line.append((x1, y1, x2, y2))
              elif x1 == x2:
                  flag = False
                  for element in v_line:
                      if abs(element[0] - x1) < 10:
                          flag = True
                          break
                  if flag == False and abs(y1 - y2) > h * 0.5:
                      v_line.append((x1, y1, x2, y2))
          return h_line, v_line
          
      def _img_split_with_shadow(gray_img, threshold_value=180):
          """
          :param binary_img: 讀入的灰度圖
          :param img_show:
          :return: 水平和垂直線的坐標集合
          """
          h = gray_img.shape[0]
          w = gray_img.shape[1]
      
          # 按行求和
          sum_x = np.sum(gray_img, axis=1)
          # 按列求和
          sum_y = np.sum(gray_img, axis=0)
      
          h_line_index = np.argwhere(sum_x < 10)
          v_line_index = np.argwhere(sum_y < 10)
      
          h_line_index = np.reshape(h_line_index, (h_line_index.shape[0],))
          v_line_index = np.reshape(v_line_index, (v_line_index.shape[0],))
      
          h_line = [(0, h_line_index[0], w - 1, h_line_index[0]), (0, h_line_index[-1], w - 1, h_line_index[-1])] if len(
              h_line_index) > 0 else []
          v_line = [(v_line_index[0], 0, v_line_index[0], h - 1), (v_line_index[-1], 0, v_line_index[-1], h - 1)] if len(
              v_line_index) > 0 else []
      
          for i in range(len(h_line_index) - 1):
              if h_line_index[i + 1] - h_line_index[i] > 2:
                  h_line.append((0, h_line_index[i], w - 1, h_line_index[i]))
      
          for i in range(len(v_line_index) - 1):
              if v_line_index[i + 1] - v_line_index[i] > 2:
                  v_line.append((v_line_index[i], 0, v_line_index[i], h - 1))
      
          return h_line, v_line
      
      
      def _combine_rect(h_lines, v_lines, w, h):
          rects = []
          # 添加第一行(列)和最后一行(列)
          x_axis = sorted(set([0, w - 1] + [item[0] for item in v_lines]))
          y_axis = sorted(set([0, h - 1] + [item[1] for item in h_lines]))
      
          point_list = []
          for y in y_axis:
              point = []
              for x in x_axis:
                  point.append((y, x))
              point_list.append(point)
      
          for y_index in range(len(y_axis) - 1):
              if y_axis[y_index + 1] - y_axis[y_index] <= 10:
                  continue
              for x_index in range(len(x_axis) - 1):
                  if x_axis[x_index + 1] - x_axis[x_index] <= 10:
                      continue
                  rects.append((y_axis[y_index], x_axis[x_index],
                                y_axis[y_index + 1], x_axis[x_index + 1]))
          return rects
      
      
      def img_split(img_file, threshold_value=180, img_show=False):
          """
      
          :param img_file: 輸入圖片路徑
          :param img_show: 是否顯示
          :return: 分割后的子圖像rect列表
          """
          img = cv2.imread(img_file, 1)
          gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
          gray = color_nomal(gray)
          # ret, binary = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY)
          h = img.shape[0]
          w = img.shape[1]
          rate = h // w if h > w else w // h
      
          h_line, v_line = _img_split_with_shadow(gray)
          if len(h_line) < 1 and len(v_line) < 1:
              h_line, v_line = _img_split_with_hough(gray)
      
          rects = _combine_rect(h_line, v_line, w, h)
          split_imgs = []
          for rect in rects:
              split_imgs.append(img[rect[0]:rect[2], rect[1]:rect[3]])
      
          if img_show:
              for rect in rects:
                  cv2.rectangle(img, (rect[1], rect[0]), (rect[3], rect[2]), (0, 255, 0), 2)        
              img = cv2.resize(img, (int(h * 0.7), int(h * 0.7 / rate)))
              cv2.imshow('cece', img)
              cv2.waitKey()
          return split_imgs
      

      分割結(jié)果
      這里寫圖片描述

      這里寫圖片描述
      這里寫圖片描述
      2. 文字方向校正,可以使用FFT變換后校正然后再逆變換回來,也可以直接使用查找包含文字區(qū)域的矩形,旋轉(zhuǎn)這個矩形,但是這種方法對于垂直的圖像就沒效果了,因為會發(fā)現(xiàn)包含文字的矩形區(qū)域就是方方正正的 不用校正。在二值化的時候采用了自適應二值化,這樣做的好處是能更精確的定位文字區(qū)域,全局二值化可能會造成有些地方一團黑。

      def rotated_img_with_fft(gray):
          # 圖像延擴
          h, w = gray.shape[:2]
          new_h = cv2.getOptimalDFTSize(h)
          new_w = cv2.getOptimalDFTSize(w)
          right = new_w - w
          bottom = new_h - h
          nimg = cv2.copyMakeBorder(gray, 0, bottom, 0, right, borderType=cv2.BORDER_CONSTANT, value=0)
      
          # 執(zhí)行傅里葉變換,并過得頻域圖像
          f = np.fft.fft2(nimg)
          fshift = np.fft.fftshift(f)
      
          fft_img = np.log(np.abs(fshift))
          fft_img = (fft_img - np.amin(fft_img)) / (np.amax(fft_img) - np.amin(fft_img))
      
          fft_img *= 255
          ret, thresh = cv2.threshold(fft_img, 150, 255, cv2.THRESH_BINARY)
      
          # 霍夫直線變換
          thresh = thresh.astype(np.uint8)
          lines = cv2.HoughLinesP(thresh, 1, np.pi / 180, 30, minLineLength=40, maxLineGap=100)
          try:
              lines1 = lines[:, 0, :]
          except Exception as e:
              lines1 = []
      
          # 創(chuàng)建一個新圖像,標注直線
          # lineimg = np.ones(nimg.shape,dtype=np.uint8)
          # lineimg = lineimg * 255
      
          piThresh = np.pi / 180
          pi2 = np.pi / 2
          angle = 0
          for line in lines1:
              # x1, y1, x2, y2 = line[0]
              x1, y1, x2, y2 = line
              # cv2.line(lineimg, (x1, y1), (x2, y2), (0, 255, 0), 2)
              if x2 - x1 == 0:
                  continue
              else:
                  theta = (y2 - y1) / (x2 - x1)
              if abs(theta) < piThresh or abs(theta - pi2) < piThresh:
                  continue
              else:
                  angle = abs(theta)
                  break
          
          angle = math.atan(angle)
          angle = angle * (180 / np.pi)
          print(angle)
          # cv2.imshow("line image", lineimg)
          center = (w // 2, h // 2)
          height_1 = int(w * fabs(sin(radians(angle))) + h * fabs(cos(radians(angle))))
          width_1 = int(h * fabs(sin(radians(angle))) + w * fabs(cos(radians(angle))))
          M = cv2.getRotationMatrix2D(center, angle, 1.0)
          M[0, 2] += (width_1 - w) / 2
          M[1, 2] += (height_1 - h) / 2
          rotated = cv2.warpAffine(gray, M, (width_1, height_1), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
          cv2.imshow('rotated', rotated)
          cv2.waitKey(0)
          return rotated
      
      
      def rotated_img_with_radiation(gray, is_show=False):
          thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
          if is_show:
              cv2.imshow('thresh', thresh)
          # 計算包含了旋轉(zhuǎn)文本的最小邊框
          coords = np.column_stack(np.where(thresh > 0))
      
          # 該函數(shù)給出包含著整個文字區(qū)域矩形邊框,這個邊框的旋轉(zhuǎn)角度和圖中文本的旋轉(zhuǎn)角度一致
          angle = cv2.minAreaRect(coords)[-1]
          print(angle)
          # 調(diào)整角度
          if angle < -45:
              angle = -(90 + angle)
          else:
              angle = -angle
          # 仿射變換
          h, w = gray.shape[:2]
          center = (w // 2, h // 2)
          print(angle)
          M = cv2.getRotationMatrix2D(center, angle, 1.0)
          rotated = cv2.warpAffine(gray, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
          if is_show:        
              cv2.putText(rotated, 'Angle: {:.2f} degrees'.format(angle), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7,
                          (0, 0, 255), 2)
              print('[INFO] angel :{:.3f}'.format(angle))
              cv2.imshow('Rotated', rotated)
              cv2.waitKey()
          return rotated
      

      這里寫圖片描述
      放射校正結(jié)果:
      這里寫圖片描述
      原圖:

      放射校正:

      fft校正,計算的時候有大概2度的誤差

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約