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

标签 python numpy opencv image-manipulation

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

代码:

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/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

关于python - 计算图形的方向以将其拉直(在Python中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59450102/

相关文章:

python - PyQt : Adding rows to QTableView using QAbstractTableModel

python - Numpy:条件总和

python - 计算 torch 张量数组的平均值和标准差

python - 从白皮书裁剪 Logo

opencv - OpenCv中的线性代数

python - 蒙特卡罗方法,在两个圆的重叠区域中飞镖

python - strip() 和 strip(string.whitespace) 给出不同的结果,尽管文档表明它们应该相同

python - Jaden 套管字符串 : How to return a sentence string with capitalised words?

python - 如何根据另一列分别统计一列中的数据?

c++ - opencv中的右键事件