计算图形的方向使其变直(在python中)

问题描述 投票:1回答:1

我有一个用于计算图形方向的代码和一个用于根据计算出的方向将图形弄直的函数。当我运行代码时,方向似乎很好,但是当函数尝试将图形弄直时,看起来图形已经变成了另一种形状。代码中可能有问题吗?

代码:

import numpy as np
import matplotlib.pyplot as plt
import cv2

img = cv2.imread('path_to_input_image',0) 
edges = cv2.Canny(img,1,2,70,3)

img = edges 
y, x = np.nonzero(img)

x = x - np.mean(x) 
y = y - np.mean(y)
coords = np.vstack([x, y])

cov = np.cov(coords) 
evals, evecs = np.linalg.eig(cov) 

sort_indices = np.argsort(evals)[::-1] 
x_v1, y_v1 = evecs[:, sort_indices[0]]  
x_v2, y_v2 = evecs[:, sort_indices[1]]

scale = 30
plt.plot([x_v1*-scale*2, x_v1*scale*2], 
         [y_v1*-scale*2, y_v1*scale*2], color='red')
plt.plot([x_v2*-scale, x_v2*scale],
         [y_v2*-scale, y_v2*scale], color='blue')
plt.plot(x, y, 'k.')
plt.axis('equal')
plt.gca().invert_yaxis()  
plt.show()

def rechtzetten(x_v1,y_v1,coords):
    theta = np.arctan((x_v1)/(y_v1))
    rotation_mat =np.matrix([[np.cos(theta), -np.sin(theta)],[np.sin(theta),np.cos(theta)]])
    transformed_mat = rotation_mat*coords


    x_transformed, y_transformed = transformed_mat.A

    fig = plt.figure()

    ax = plt.Axes(fig, [0.,0.,1.,1.])
    ax.set_axis_off()
    fig.add_axes(ax)
    ax = plt.plot(x_transformed,y_transformed)

    plt.savefig("ja.png",pdi=300)
    plt.show(ax)
    #plt.savefig("rotation.png") 
    img3 = cv2.imread('ja.png',100)
    edges2 = cv2.Canny(img3,1,4)

    cv2.imwrite('rotated_with_border.png', edges2)
    return transformed_mat, edges2

transformed_mat, edges = rechtzetten(x_v1,y_v1,coords)

我使用的输入图像:

enter image description here

我得到的输出:

enter image description here

输出的第一图使用蓝轴和红轴显示方向。输出的第二个图形应该是第一个图形的精简版本。

**理顺,我的意思是使第一个图形上的蓝色和红色轴与基本坐标系上的x和y轴匹配。

python numpy opencv image-manipulation
1个回答
1
投票

这是在Python / OpenCV中使用旋转的边界矩形进行去偏斜的一种方法

输入:

enter image description here

import cv2
import numpy as np

# load image
img = cv2.imread("object.png")

# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold the grayscale image
ret, thresh = cv2.threshold(gray,0,255,0)

# find outer contour
cntrs = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]

# get rotated rectangle from contour
rotrect = cv2.minAreaRect(cntrs[0])
box = cv2.boxPoints(rotrect)
box = np.int0(box)

# draw rotated rectangle on copy of img
rot_bbox = img.copy()
cv2.drawContours(rot_bbox,[box],0,(0,0,255),2)

# get orientation angle relative to horizontal of the rotated rectangle
angle = rotrect[-1]

# from https://www.pyimagesearch.com/2017/02/20/text-skew-correction-opencv-python/
# the `cv2.minAreaRect` function returns values in the
# range [-90, 0); as the rectangle rotates clockwise the
# returned angle tends to 0 -- in this special case we
# need to add 90 degrees to the angle
if angle < -45:
    angle = -(90 + angle)

# otherwise, just take the negative of the angle to make
# it positive
else:
    angle = -angle

print(angle,"deg")

# negate the angle for deskewing
neg_angle = -angle

# Get rotation matrix
(h, w) = img.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, neg_angle, scale=1.0)

# rotate the image to deskew it
deskewed = cv2.warpAffine(img, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)


cv2.imshow("THRESH", thresh)
cv2.imshow("ROTATED BBOX", rot_bbox)
cv2.imshow("DESKEWED", deskewed)
cv2.waitKey(0)
cv2.destroyAllWindows()

# write result to disk
cv2.imwrite("object_deskewed.png", deskewed)

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.