计算图形的方向以将其拉直(在 python 中)

Calculating the orientation of a figure to straighten it out (in python)

我有一个计算图形方向的代码和一个根据计算出的方向拉直图形的函数。当我 运行 代码时,方向似乎很好,但是当函数试图拉直图形时,它看起来像图形已经变成了另一种形状。难道代码有问题?

代码:

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)

我使用的输入图片:

我得到的输出:

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

*我所说的理顺是指将第一个图上的蓝色和红色轴与基本坐标系上的 x 和 y 轴匹配。

这是使用 Python/OpenCV

中旋转的边界矩形进行校正的一种方法

输入:

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)