图像角点度计算的脚本怎么写?
how to write the script for image corner degree calculation?
我有超过 100 张图片,每张图片的角度都不一样。我写了一个基本的 python 代码来将每个图像从任何角度一个一个地旋转到零度(我的意思是使它们变平)。我附加的 python 代码是一个简单的代码,不幸的是它不会自动找到角度,也不会使其精确为零。任何时候对于任何图像,我都应该多次找到角度和 运行 代码以使其为零(有时我无法使其完全平坦或我们将其设为零度)。根据我附加的图像,image1 是作为输入的示例图像之一,image_2 是我希望最后作为输出的旋转图像。
我想请任何人帮助我修改当前代码或提供新的 python 代码(我更喜欢新代码),我可以使我的图像从任何角度旋转到零度。
如果需要,请随时向我询问更多解释。
我的opencv-python代码是:
import cv2
import numpy as np
img = cv2.imread('image1.tif')
num_rows, num_cols = img.shape[:2]
rotation_matrix = cv2.getRotationMatrix2D((num_cols/2, num_rows/2),69.4, 1)
img_rotation = cv2.warpAffine(img, rotation_matrix, (num_cols, num_rows))
cv2.imshow('Rotation', img_rotation)
cv2.imwrite('image_2.tif',img_rotation)
cv2.waitKey()
注意:输入和输出图像已删除。
这绝对不是最可靠的方法,但也许可以选择:
- 假设边界全黑
- 识别图像的最上角 (x0,y0)/最右角 (x1,y1)
- 计算旋转角度为
alpha = math.atan2(x1-x0,y1-y0)
我下载了你的图(它在 imgur 上被转换为 png)并测试了程序:
#!/usr/bin/env python
import cv2
import math
import numpy as np
img = cv2.imread('test.png')
H, W = img.shape[:2]
x0,y0 = None,None
x1,y1 = None,None
#scan all rows starting with the first
for i in range(0, H):
row = img[i].sum(axis=1)
s = np.sum(row)
if s:
#if there is at least one non-black pixel, mark
#its position
x0 = np.max(np.where(row>0))
y0 = i
break
#scan all columns starting with the right-most one
for j in range(W-1,-1,-1):
col = img[:,j,:].sum(axis=1)
s = np.sum(col)
if s:
#mark the position of the first non-black pixel
x1 = j
y1 = np.min(np.where(col>0))
break
dx = x1 - x0
dy = y1 - y0
alpha = math.atan2(dx, dy) / math.pi * 180
rotation_matrix = cv2.getRotationMatrix2D((W/2, H/2), -alpha, 1)
img_rotation = cv2.warpAffine(img, rotation_matrix, (W, H))
cv2.imwrite('image_2.tif',img_rotation)
编辑:
如果 "corner" 像素也为黑色,则先前的方法可能不准确,从而导致计算出的角度出现偏差。更准确的方法可能如下:
- 确定矩形的"upper"边界(即定义边缘的像素坐标)
- 取x轴投影较长的边
- 拟合坐标以计算定义边缘的线的斜率
实施:
#!/usr/bin/env python
import cv2
import math
import numpy as np
img = cv2.imread('test.png')
H, W = img.shape[:2]
data = []
for j in range(0, W):
col = img[:,j,:].sum(axis=1)
s = np.sum(col)
if not s:
continue
for i in range(0, H):
if col[i] > 0:
data.append((j, i))
break
y_min, min_pos = None, None
for idx, (x, y) in enumerate(data):
if y_min is None or y < y_min:
y_min = y
min_pos = idx
N = len(data)
if min_pos > N - min_pos:
data = data[:min_pos]
else:
data = data[min_pos:]
data = np.asarray(data).T
coeffs = np.polyfit(data[0], data[1], 1)
alpha = math.atan(coeffs[0]) / math.pi * 180
print(alpha)
rotation_matrix = cv2.getRotationMatrix2D((W/2, H/2), alpha, 1)
img_rotation = cv2.warpAffine(img, rotation_matrix, (W, H))
cv2.imwrite('image_2.tif',img_rotation)
另一种找到角度的方法是(假设图像在黑色背景上):
- 将图像转换为灰度
- 使用阈值分割图像
- 找到图像的轮廓
求出符合等高线的椭圆参数
import cv2
import numpy as np
image = cv2.imread("DlYEa.png")
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
num_rows, num_cols = image.shape[:2]
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
img, contours, hier = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
(x, y), (Ma, ma), angle = cv2.fitEllipse(cnt)
angle = int(angle - 90)
rotation_matrix = cv2.getRotationMatrix2D((num_cols/2, num_rows/2), angle, 1)
img_rotation = cv2.warpAffine(image, rotation_matrix, (num_cols, num_rows))
cv2.imshow("rotation", img_rotation)
cv2.waitKey()
cv2.destroyAllWindows()
我有超过 100 张图片,每张图片的角度都不一样。我写了一个基本的 python 代码来将每个图像从任何角度一个一个地旋转到零度(我的意思是使它们变平)。我附加的 python 代码是一个简单的代码,不幸的是它不会自动找到角度,也不会使其精确为零。任何时候对于任何图像,我都应该多次找到角度和 运行 代码以使其为零(有时我无法使其完全平坦或我们将其设为零度)。根据我附加的图像,image1 是作为输入的示例图像之一,image_2 是我希望最后作为输出的旋转图像。 我想请任何人帮助我修改当前代码或提供新的 python 代码(我更喜欢新代码),我可以使我的图像从任何角度旋转到零度。 如果需要,请随时向我询问更多解释。
我的opencv-python代码是:
import cv2
import numpy as np
img = cv2.imread('image1.tif')
num_rows, num_cols = img.shape[:2]
rotation_matrix = cv2.getRotationMatrix2D((num_cols/2, num_rows/2),69.4, 1)
img_rotation = cv2.warpAffine(img, rotation_matrix, (num_cols, num_rows))
cv2.imshow('Rotation', img_rotation)
cv2.imwrite('image_2.tif',img_rotation)
cv2.waitKey()
注意:输入和输出图像已删除。
这绝对不是最可靠的方法,但也许可以选择:
- 假设边界全黑
- 识别图像的最上角 (x0,y0)/最右角 (x1,y1)
- 计算旋转角度为
alpha = math.atan2(x1-x0,y1-y0)
我下载了你的图(它在 imgur 上被转换为 png)并测试了程序:
#!/usr/bin/env python
import cv2
import math
import numpy as np
img = cv2.imread('test.png')
H, W = img.shape[:2]
x0,y0 = None,None
x1,y1 = None,None
#scan all rows starting with the first
for i in range(0, H):
row = img[i].sum(axis=1)
s = np.sum(row)
if s:
#if there is at least one non-black pixel, mark
#its position
x0 = np.max(np.where(row>0))
y0 = i
break
#scan all columns starting with the right-most one
for j in range(W-1,-1,-1):
col = img[:,j,:].sum(axis=1)
s = np.sum(col)
if s:
#mark the position of the first non-black pixel
x1 = j
y1 = np.min(np.where(col>0))
break
dx = x1 - x0
dy = y1 - y0
alpha = math.atan2(dx, dy) / math.pi * 180
rotation_matrix = cv2.getRotationMatrix2D((W/2, H/2), -alpha, 1)
img_rotation = cv2.warpAffine(img, rotation_matrix, (W, H))
cv2.imwrite('image_2.tif',img_rotation)
编辑:
如果 "corner" 像素也为黑色,则先前的方法可能不准确,从而导致计算出的角度出现偏差。更准确的方法可能如下:
- 确定矩形的"upper"边界(即定义边缘的像素坐标)
- 取x轴投影较长的边
- 拟合坐标以计算定义边缘的线的斜率
实施:
#!/usr/bin/env python
import cv2
import math
import numpy as np
img = cv2.imread('test.png')
H, W = img.shape[:2]
data = []
for j in range(0, W):
col = img[:,j,:].sum(axis=1)
s = np.sum(col)
if not s:
continue
for i in range(0, H):
if col[i] > 0:
data.append((j, i))
break
y_min, min_pos = None, None
for idx, (x, y) in enumerate(data):
if y_min is None or y < y_min:
y_min = y
min_pos = idx
N = len(data)
if min_pos > N - min_pos:
data = data[:min_pos]
else:
data = data[min_pos:]
data = np.asarray(data).T
coeffs = np.polyfit(data[0], data[1], 1)
alpha = math.atan(coeffs[0]) / math.pi * 180
print(alpha)
rotation_matrix = cv2.getRotationMatrix2D((W/2, H/2), alpha, 1)
img_rotation = cv2.warpAffine(img, rotation_matrix, (W, H))
cv2.imwrite('image_2.tif',img_rotation)
另一种找到角度的方法是(假设图像在黑色背景上):
- 将图像转换为灰度
- 使用阈值分割图像
- 找到图像的轮廓
求出符合等高线的椭圆参数
import cv2 import numpy as np image = cv2.imread("DlYEa.png") gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) num_rows, num_cols = image.shape[:2] _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY) img, contours, hier = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnt = contours[0] (x, y), (Ma, ma), angle = cv2.fitEllipse(cnt) angle = int(angle - 90) rotation_matrix = cv2.getRotationMatrix2D((num_cols/2, num_rows/2), angle, 1) img_rotation = cv2.warpAffine(image, rotation_matrix, (num_cols, num_rows)) cv2.imshow("rotation", img_rotation) cv2.waitKey() cv2.destroyAllWindows()