transformación detallada perspectiva con los principios del código - la división y la corrección de Poker


Introducción
En el artículo anterior, se introdujo la transformación afín, sólo tenemos dos líneas a través de una matriz de transformación M tres sería capaz de lograr la bandeja de imágenes, hacer zoom, flip, operación de rotación. Nos encontramos con que estas transformaciones en realidad pertenecen a la transformación de plano, si queremos transformar el espacio todavía?

FIG cartas de juego superior extrajeron de forma individual, como se muestra en la figura.

En este momento debemos ser cómo lograr esta función? Este hecho implica una transformación espacial de la imagen, tenemos que utilizar lo que llamamos una transformación de perspectiva.

Perspectiva transformación
perspectiva transformada (Perspectiva Transformación) se refiere al punto de la imagen uso perspectiva central, la condición del punto objetivo son colineales, la rotación del cojinete de acuerdo con la ley de la perspectiva Películas superficie (superficie S) sobre una traza (eje perspectiva) se hace girar un cierto ángulo, destruir el haz de luz de proyección original, podemos mantener el mismo plano geométrico de la transformación Películas de cojinete de proyección. Brevemente, un avión se proyecta a través de una matriz de proyección al plano especificado.

principio analítico de
la transformación de perspectiva fórmula transformación general:



 
    

8 por la ecuación anterior, podemos resolver para los ocho parámetros para obtener la matriz de transformación de perspectiva, y finalmente hemos conseguido mediante el uso de la transformación de perspectiva a través de la matriz de transformación perspectiva opencv método warpPerspective, entonces ejemplo mediante la unión a un uso particular ella.
Perspectiva ejemplos de transformación de explicar
donde se nos dimos cuenta principalmente a través de las características descritas anteriormente opencv

imagen de lectura

#读取图像
img = cv2.imread("poker.jpeg")
#将原图转为灰度图
gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)


detección de bordes de Canny
análisis parámetro de función Canny:

matriz de imagen de entrada: Imagen
Threshold1: mínimo valor umbral
threshold2: más caros de umbral
bordes: una salida de imagen borde, un solo canal de 8 bits imagen
apertureSize: Sobel tamaño operador
L2gradient: indica un valor booleano, si es cierto, utilizar el más preciso norma L2 se calcula, utilizando la norma L1 o

#Canny边缘检测
canny_img = cv2.Canny(gray_img,100,150,3)
#显示边缘检测后的图像
cv2.imshow("canny_img",canny_img)
cv2.waitKey(0)


Hough línea de detección
análisis parámetro de función HoughLinesP:

Image: Después de salida de la imagen de detección de bordes de Canny
rho: valores de radio polares r a una resolución en unidades de píxeles, por lo general sólo un píxel
theta: ángulo polar polar θ \ thetaθ en radianes unidad de resolución se utiliza generalmente 1 grado
umbral: el mínimo requerido para detectar una curva de intersección rectas
líneas: líneas rectas detectados almacenados, que comprende empezando y terminando coordenadas de la línea
minLineLength: un número mínimo de puntos de componentes de una línea recta, la línea recta es menor que el número de puntos a ser desechados
maxLineGap: en la distancia máxima de un punto sobre una línea recta

def draw_line(img,lines):
    # 绘制直线
    for line_points in lines:
        cv2.line(img,(line_points[0][0],line_points[0][1]),(line_points[0][2],line_points[0][3]),
                 (0,255,0),2,8,0)
    cv2.imshow("line_img", img)
    cv2.waitKey(0)
# #Hough直线检测
lines = cv2.HoughLinesP(canny_img,1,np.pi/180,70,minLineLength=30,maxLineGap=10)
#基于边缘检测的图像来检测直线
draw_line(img,lines)


El cálculo de las coordenadas de los vértices
de coordenadas de intersección calcular mediante una coordenada línea recta que une los dos puntos extremos, la posición de las cartas de juego para encontrar cuatro vértices

#计算四条直线的交点作为顶点坐标
def computer_intersect_point(lines):
    def get_line_k_b(line_point):
        """计算直线的斜率和截距
        :param line_point: 直线的坐标点
        :return:
        """
        #获取直线的两点坐标
        x1,y1,x2,y2 = line_point[0]
        #计算直线的斜率和截距
        k = (y1 - y2)/(x1 - x2)
        b = y2 - x2 * (y1 - y2)/(x1 - x2)
        return k,b
    #用来存放直线的交点坐标
    line_intersect = []
    for i in range(len(lines)):
        k1,b1 = get_line_k_b(lines[i])
        for j in range(i+1,len(lines)):
            k2,b2 = get_line_k_b(lines[j])
            #计算交点坐标
            x = (b2 - b1) / (k1 - k2)
            y = k1 * (b2 - b1)/(k1 -k2) + b1
            if x > 0 and y > 0:
                line_intersect.append((int(np.round(x)),int(np.round(y))))
    return line_intersect
def draw_point(img,points):
    for position in points:
        cv2.circle(img,position,5,(0,0,255),-1)
    cv2.imshow("draw_point",img)
    cv2.waitKey(0)
#计算直线的交点坐标
line_intersect = computer_intersect_point(lines)
#绘制交点坐标的位置
draw_point(img,line_intersect)


Clasificación de las coordenadas de los vértices
antes de calcular las coordenadas de la matriz de transformación de perspectiva tenemos que corresponden a las coordenadas de imagen de la imagen de transformar los elementos, de acuerdo a la izquierda -> en -> derecho - Solicitar> bajo

def order_point(points):
    """对交点坐标进行排序
    :param points:
    :return:
    """
    points_array = np.array(points)
    #对x的大小进行排序
    x_sort = np.argsort(points_array[:,0])
    #对y的大小进行排序
    y_sort = np.argsort(points_array[:,1])
    #获取最左边的顶点坐标
    left_point = points_array[x_sort[0]]
    #获取最右边的顶点坐标
    right_point = points_array[x_sort[-1]]
    #获取最上边的顶点坐标
    top_point = points_array[y_sort[0]]
    #获取最下边的顶点坐标
    bottom_point = points_array[y_sort[-1]]
    return np.array([left_point,top_point,right_point,bottom_point],dtype=np.float32)
def target_vertax_point(clockwise_point):
    #计算顶点的宽度(取最大宽度)
    w1 = np.linalg.norm(clockwise_point[0]-clockwise_point[1])
    w2 = np.linalg.norm(clockwise_point[2]-clockwise_point[3])
    w = w1 if w1 > w2 else w2
    #计算顶点的高度(取最大高度)
    h1 = np.linalg.norm(clockwise_point[1]-clockwise_point[2])
    h2 = np.linalg.norm(clockwise_point[3]-clockwise_point[0])
    h = h1 if h1 > h2 else h2
    #将宽和高转换为整数
    w = int(round(w))
    h = int(round(h))
    #计算变换后目标的顶点坐标
    top_left = [0,0]
    top_right = [w,0]
    bottom_right = [w,h]
    bottom_left = [0,h]
    return np.array([top_left,top_right,bottom_right,bottom_left],dtype=np.float32)
#对原始图像的交点坐标进行排序
clockwise_point = order_point(line_intersect)
#获取变换后坐标的位置
target_clockwise_point = target_vertax_point(clockwise_point)


Cálculo de una matriz de transformada para una conversión perspectiva

#计算变换矩阵
matrix = cv2.getPerspectiveTransform(clockwise_point,target_clockwise_point)
print(matrix)
#计算透视变换后的图片
perspective_img = cv2.warpPerspective(img,matrix,(target_clockwise_point[2][0],target_clockwise_point[2][1]))
cv2.imshow("perspective_img",perspective_img)
cv2.waitKey(0)

 

[[ 1.34133640e+00 -8.01200936e-01 -2.49362538e+01]
 [ 7.10053715e-01  1.67369804e+00 -1.62145838e+02]
 [ 2.49859580e-04  3.44969838e-03  1.00000000e+00]]

 

Publicado 86 artículos originales · ganado elogios 267 · Vistas 1,77 millones +

Supongo que te gusta

Origin blog.csdn.net/javastart/article/details/104325795
Recomendado
Clasificación