从扫描文档中的雷达图中提取数据

时间:2019-06-02 23:44:51

标签: python opencv radar-chart

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

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

enter image description here

1 个答案:

答案 0 :(得分:0)

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

1。找到圆心(也许使用HoughCircle函数)

2。反阈值突出显示深灰色区域

3。调用opencv函数rox来获取表示该区域的多边形

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并执行反向旋转翻译)