小能豆

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

py

我有一段计算图形方向的代码和一个根据计算出的方向拉直图形的函数。当我运行代码时,方向似乎没问题,但当函数试图拉直图形时,图形似乎变成了另一种形状。代码中可能出了什么问题吗?

守则:

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)

我使用的输入图像:

1.png

我得到的输出:

2.jpg

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

* 理顺的意思是将第一个图上的蓝轴和红轴与基本坐标系上的 x 轴和 y 轴相匹配。


阅读 11

收藏
2024-12-09

共1个答案

小能豆

以下是使用 Python/OpenCV 中的旋转边界矩形进行倾斜校正的一种方法

输入:

1.png

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)

2.png

2024-12-09