• Detect Vertical&Horizontal Segments By OpenCV


    Detect Vertical&Horizontal Segments By OpenCV,and Save the data to csv.

    Steps:

    1. Using adaptiveThreshold to generate thresholded image.
    2. Using threshold to find lines.
    3. Save the data to csv by convert it to json.
      1 # coding=gbk
      2 import cv2
      3 import numpy as np
      4 import json
      5 import csv
      6 import os
      7 
      8 def find_lines(threshold, regions=None, direction='horizontal',
      9                line_scale=15, iterations=0):
     10     """Finds horizontal and vertical lines by applying morphological
     11     transformations on an image.
     12 
     13     Parameters
     14     ----------
     15     threshold : object
     16         numpy.ndarray representing the thresholded image.
     17     regions : list, optional (default: None)
     18         List of page regions that may contain tables of the form x1,y1,x2,y2
     19         where (x1, y1) -> left-top and (x2, y2) -> right-bottom
     20         in image coordinate space.
     21     direction : string, optional (default: 'horizontal')
     22         Specifies whether to find vertical or horizontal lines.
     23     line_scale : int, optional (default: 15)
     24         Factor by which the page dimensions will be divided to get
     25         smallest length of lines that should be detected.
     26 
     27         The larger this value, smaller the detected lines. Making it
     28         too large will lead to text being detected as lines.
     29     iterations : int, optional (default: 0)
     30         Number of times for erosion/dilation is applied.
     31 
     32         For more information, refer `OpenCV's dilate <https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html#dilate>`_.
     33 
     34     Returns
     35     -------
     36     dmask : object
     37         numpy.ndarray representing pixels where vertical/horizontal
     38         lines lie.
     39     lines : list
     40         List of tuples representing vertical/horizontal lines with
     41         coordinates relative to a left-top origin in
     42         image coordinate space.
     43 
     44     """
     45     lines = []
     46 
     47     if direction == 'vertical':
     48         size = threshold.shape[0] // line_scale
     49         el = cv2.getStructuringElement(cv2.MORPH_RECT, (1, size))
     50     elif direction == 'horizontal':
     51         size = threshold.shape[1] // line_scale
     52         el = cv2.getStructuringElement(cv2.MORPH_RECT, (size, 1))
     53     elif direction is None:
     54         raise ValueError("Specify direction as either 'vertical' or"
     55                          " 'horizontal'")
     56 
     57     if regions is not None:
     58         region_mask = np.zeros(threshold.shape)
     59         for region in regions:
     60             x, y, w, h = region
     61             region_mask[y : y + h, x : x + w] = 1
     62         threshold = np.multiply(threshold, region_mask)
     63 
     64     threshold = cv2.erode(threshold, el)
     65     threshold = cv2.dilate(threshold, el)
     66     dmask = cv2.dilate(threshold, el, iterations=iterations)
     67 
     68     try:
     69         _, contours, _ = cv2.findContours(
     70             threshold.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
     71     except ValueError:
     72         # for opencv backward compatibility
     73         contours, _ = cv2.findContours(
     74             threshold.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
     75 
     76     for c in contours:
     77         x, y, w, h = cv2.boundingRect(c)
     78         x1, x2 = x, x + w
     79         y1, y2 = y, y + h
     80         if direction == 'vertical':
     81             lines.append(((x1 + x2) // 2, y2, (x1 + x2) // 2, y1))
     82         elif direction == 'horizontal':
     83             lines.append((x1, (y1 + y2) // 2, x2, (y1 + y2) // 2))
     84 
     85     return dmask, lines
     86 
     87 def adaptive_threshold(imagename, process_background=False, blocksize=15, c=-2):
     88     """Thresholds an image using OpenCV's adaptiveThreshold.
     89 
     90     Parameters
     91     ----------
     92     imagename : string
     93         Path to image file.
     94     process_background : bool, optional (default: False)
     95         Whether or not to process lines that are in background.
     96     blocksize : int, optional (default: 15)
     97         Size of a pixel neighborhood that is used to calculate a
     98         threshold value for the pixel: 3, 5, 7, and so on.
     99 
    100         For more information, refer `OpenCV's adaptiveThreshold <https://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html#adaptivethreshold>`_.
    101     c : int, optional (default: -2)
    102         Constant subtracted from the mean or weighted mean.
    103         Normally, it is positive but may be zero or negative as well.
    104 
    105         For more information, refer `OpenCV's adaptiveThreshold <https://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html#adaptivethreshold>`_.
    106 
    107     Returns
    108     -------
    109     img : object
    110         numpy.ndarray representing the original image.
    111     threshold : object
    112         numpy.ndarray representing the thresholded image.
    113 
    114     """
    115     img = cv2.imread(imagename)
    116     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    117 
    118     if process_background:
    119         threshold = cv2.adaptiveThreshold(
    120             gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    121             cv2.THRESH_BINARY, blocksize, c)
    122     else:
    123         threshold = cv2.adaptiveThreshold(
    124             np.invert(gray), 255,
    125             cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, blocksize, c)
    126     return img, threshold
    127 
    128 count = 0
    129 root = 'E:/VGID_Text/Mycode/linelabel/PDF_JPG/'
    130 rows=[]
    131 for root, dirs, files in os.walk(root):
    132     for img in files:
    133         if img.endswith('jpg'):
    134             img_path = root+'/'+img
    135             image, threshold = adaptive_threshold(img_path)
    136             find_lines(threshold)
    137             vertical_mask, vertical_segments = find_lines(threshold, direction='vertical')
    138             horizontal_mask, horizontal_segments = find_lines(threshold, direction='horizontal')
    139             lines_list = vertical_segments + horizontal_segments
    140             objects = []
    141             lines_dict = {"objects":objects}
    142             for line in lines_list:
    143                 point1 = {"x": line[0], "y": line[1]}
    144                 point2 = {"x": line[2], "y": line[3]}
    145                 ptList = [point1,point2]
    146                 polygon = {"ptList":ptList}
    147                 line_dict ={"polygon":polygon,
    148                             "name": "line",
    149                             "type": 4,
    150                             "color": "#aa40bf",
    151                             "id": "6173cf75-ea09-4ff4-a75e-5cc99a5ea40e",
    152                             "cur": 0,
    153                             "lineStyle": "solid"
    154                             }
    155                 objects.append(line_dict)
    156             lines_json = json.dumps(lines_dict)
    157             print(count, lines_json)
    158             row = [img_path, lines_json]
    159             rows.append(row)
    160             count = count + 1
    161 with open('E:/线条标注3k+.csv', 'w', newline='') as csv_file:
    162     csv_writer = csv.writer(csv_file)
    163     csv_writer.writerow(['image_path','lines'])
    164     for row in rows:
    165         csv_writer.writerow(row)

    Reference:Camelot:https://camelot-py.readthedocs.io/en/master/

  • 相关阅读:
    Spring Security OAuth2 源码分析
    Spring Security OAuth2 token权限隔离
    Spring Cloud Feign 使用OAuth2
    Spring Security OAuth2 授权码模式
    全链路追踪spring-cloud-sleuth-zipkin
    Spring Security OAuth2 授权失败(401) 问题整理
    使用ShardingJdbc分表
    Kubectl常用命令
    Spring Cloud Zuul实现IP访问控制
    一次非核心接口(信息提示类)被刷引发的思考
  • 原文地址:https://www.cnblogs.com/wind-chaser/p/10908180.html
Copyright © 2020-2023  润新知