【问题标题】:Extracting data from a radar chart in a scanned document从扫描文档中的雷达图中提取数据
【发布时间】:2019-06-02 23:44:51
【问题描述】:

我想将此雷达图转换为每个组件(虚线)的数值,使用 python 的 openCV。我将如何最好地做到这一点?我一直在考虑检测图形的中心以及虚线与灰色区域的交点。通过这样做,我可以测量中心和每个交叉点之间的距离,以确定每个组件的值。然而,这似乎相当复杂,我不知道如何开始。有人可以帮我吗?

编辑:目的是编写一个可以从 250 个这些图表中提取数据的软件。 (我的扫描质量更好)

【问题讨论】:

    标签: python opencv radar-chart


    【解决方案1】:

    我会做这样的事情(对不起,这是伪代码,如果你认为这个想法足够好,我会尝试编写一些真正的代码):

    1.找到圆心(可以使用HoughCircle函数)

    2.逆阈值突出你的深灰色区域

    3.调用opencv函数 approx poly 得到代表这个区域的多边形

    4.对于每个顶点,测量它与中心的距离并将其转换为您想要的比例

    我认为应该可以。

    霍夫圆教程 https://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html

    近似聚教程
    https://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html

    编辑

    我有一些空闲时间,所以我写了一段初始代码来提取圆、半径和多边形,希望对你有所帮助

        img = cv.imread("c:\\temp\\test.jpg", cv.IMREAD_COLOR) 
        gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    
        #thresholds for isolate circle and poly
        ret, thres_poly_temp = cv.threshold(gray, 90, 255, cv.THRESH_BINARY_INV)
        ret, thres_circle = cv.threshold(gray, 110, 255, cv.THRESH_BINARY_INV)
    
        #cleanup image for detect poly
        thres_poly = thres_poly_temp.copy()
        thres_poly = cv.GaussianBlur(thres_poly_temp,(3,3),0)
        thres_poly = cv.medianBlur( thres_poly, 5)
    
        #bitwise_and to keep just the poly, removing the circle 
        cv.bitwise_and(thres_poly_temp, thres_circle, thres_poly)
        kernel = np.ones((3, 3),np.uint8)
        thres_poly  = cv.morphologyEx(thres_poly, cv.MORPH_CLOSE, kernel)
        kernel = np.ones((3, 3),np.uint8)
        thres_poly  = cv.morphologyEx(thres_poly, cv.MORPH_OPEN, kernel)
    
        #find circle
        circle = cv.HoughCircles(thres_circle, 3, 2, 800, minRadius = 100, maxRadius=500, param1=80, param2=100)
        radius_list = []
        if circle is not None:
            circle = np.round(circle[0, :]).astype("int")
            for (x,y,r) in circle:
                cv.circle(gray, (x,y), r, (255,255,0),3)
                cv.circle(gray, (x,y), 3, (255,255,0),3)
                radius_list.append((x+r,y))
                a = 0
                #find radius
                while(a < 360):
                    rad = math.radians(a)
                    x2 = int((radius_list[0][0] - x) * math.cos(rad)) - int((radius_list[0][1] - y) * math.sin(rad)) + x;
                    y2 = int((radius_list[0][0] - x) * math.sin(rad)) + int((radius_list[0][1] - y) * math.cos(rad)) + y;
                    radius_list.append((x2,y2))
                    a = a + 18
                    cv.line(gray, (x,y), (x2,y2), (255,255,0),2)
    
        #find poly contour
        contours,hierarchy = cv.findContours(thres_poly, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    
        #extract contour with max area
        maxArea = -1
        maxAreaContour = contours[0]
        for contour in contours:
            area = abs(cv.contourArea(contour))
            if area > maxArea:
                maxArea = area
                maxAreaContour = contour
    
        #approx poly to get contours
        epsilon = 0.1*cv.arcLength(maxAreaContour,True)
        approx = cv.approxPolyDP(maxAreaContour, 5, True)
        cv.drawContours(gray, [approx],-1,(0,255,0),2)
        cv.imshow("1", gray)
    
        #now just iterate all the radius with the contour to find the intersection
        # it should be pretty straight forward
    

    output sample

    编辑 2:仍然缺少:对齐图像,正如我所说,您可以使用水平和垂直虚线来做到这一点(使用霍夫线来获取它们,然后确定 m 和 q 并执行逆旋转翻译)

    【讨论】:

    • 问题是它可能找不到顶点,如果灰色一直保持直线。例如看绿色的“HOP”区域。那里有 3 个分量的值或多或少相同,因此中间线上没有角度。同样,当查看棕色的“WILDE FLORA”段时,我们可以看到那里没有任何灰色区域,因此这里也不会检测到顶点......
    • 你说得对,我没有注意到...你认为在点 3 处找到刚刚找到的多边形与圆半径之间的交点以确定值?
    • 您可以使用左上角的虚线对齐图像,然后您知道每 18 度有一个半径(每季度 5 个),因此您可以进行数学运算并找到所有半径坐标,然后检查它们与多边形的交点
    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 2010-12-17
    相关资源
    最近更新 更多