Polyline Approximate Curve Program

principle:

Douglas-Peucker algorithm (Douglas-Peucker) to achieve. The algorithm is also named Douglas-Peucker algorithm and iterative endpoint fitting algorithm. It is an algorithm that approximates the curve as a series of points and reduces the number of points . The original types of the algorithm were proposed by Urs Ramer in 1972, and David Douglas and Thomas Peucker in 1973, and were used in the following decades. It was improved by other scholars.

The classic Douglas-Peucker algorithm is described as follows:

(1) Connect a straight line AB between the two points A and B at the beginning and the end of the curve, which is the chord of the curve;

(2) Obtain the point C on the curve with the largest distance from the straight line segment, and calculate the distance d from AB;

(3) Compare the size of the distance with the predetermined threshold threshold. If it is less than the threshold, then the straight line segment is regarded as an approximation of the curve, and the processing of this segment of the curve is completed.

(4) If the distance is greater than the threshold, use C to divide the curve into two sections, AC and BC, and perform 1~3 processing on the two sections respectively.

(5) When all the curves have been processed, the polyline formed by connecting each dividing point in turn can be used as an approximation of the curve.

achieve:

There are some details; such as marking connected areas, the usage of connected area attributes, how to superimpose characters on the graph, the application of arctangent function, etc.

#encoding=utf-8
import cv2
import numpy as np
from skimage import measure
from skimage import morphology
import torch
import math
 


def threshold_demo(image):
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 
    #//ret, binary = cv2.threshold(gray, 0, 255, 100)
    #//print("threshold value %s"%ret)
    binary = np.zeros((720,1280),dtype=np.uint8)
    for u in range(720):
        for v in range(1280):
            if gray[u, v] < 10:
                binary[u, v] = 255	

    return binary
    
if __name__ == '__main__':
    oimg = cv2.imread('111.jpg')
    img = threshold_demo(oimg)
    cv2.imwrite("11111111.jpg", img)

    flagimg = np.zeros((720,1280),dtype=np.uint8)
    for u in range(720):
        for v in range(1280):
            if img[u, v] > 200:
                flagimg[u, v] = 1	

    skeleton =morphology.skeletonize(flagimg)

    flagimgx = np.zeros((720,1280),dtype=np.uint8)
    for u in range(720):
        for v in range(1280):
            if skeleton[u, v] > 0:
                flagimgx[u, v] = 255

    lable =  measure.label(flagimgx,  connectivity = 2)
    props = measure.regionprops(lable, intensity_image=None, cache=True)

    for i in range(len(props)):
        y0, x0, y1, x1 = props[i].bbox
        flagmax = 0;
        labelv = props[i].label
        for j in range(len(props[i].coords)):
            y,x = props[i].coords[j]
            flag = 0
            if y > 1 and y < 720 - 1 and x > 1 and x < 1280 - 1:
                for l in range(y -1 ,y + 2):
                    for r in range(x -1 ,x + 2):
                        if lable[l ,r] == labelv:
                            flag += 1
            if flag > flagmax:
                flagmax = flag
            if flag >= 4:
                flagimgx[y, x] = 0

    cv2.imwrite("middle.jpg", flagimgx)


    lable =  measure.label(flagimgx,  connectivity = 2)
    props = measure.regionprops(lable, intensity_image=None, cache=True)
    num = 0
    for i in range(len(props)):
        are = props[i].area
        #print("are = ", are)
        if are > 172 and are < 200:
            approx = cv2.approxPolyDP(props[i].coords, 1, False)
            for u in range(len(approx) - 1):
                y,x = approx[u][0]
                flagimgx[y, x] = 100
                font=cv2.FONT_HERSHEY_SIMPLEX
                numx ='%d'%num
                flagimgx = cv2.putText(flagimgx,numx,(x, y),font,0.5,(255,255,255),1)
                y1,x1 = approx[u + 1][0]
                # 斜率
                aratio = (y1 - y) / (x1 - x)
                print("num = ", aratio)
                ang = math.atan(aratio)
                ang = (ang * 180) / 3.1415926
                print("ang = ", ang)
                num = num + 1
    cv2.imwrite("22222222.jpg", flagimgx)

 

Guess you like

Origin blog.csdn.net/gbz3300255/article/details/110532337