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