目前,我正在使用下面的代码来拍摄一张图像,其中每列像素代表真实的世界中不同的宽度(mm)。想象一下,一个标签缠绕在一个瓶子上。我的输入图像是当你直视瓶子时看到的(较少透视)。我试图解开标签,使展平的结果有一个精确的1 pixel:1 mm的比例。瓶子也不是圆形的,但我有一个方程式来表示它的曲率。有没有更好的方法来做到这一点,结果总是相同的,并且解拉伸的图像更均匀?
见下面的顶部图像是原始图像,底部是我希望实现的。
下面的等式和曲线给出了每列像素的压缩因子,其中列1741处的像素表示0.773802mm
目前,我使用下面的概率代码根据压缩因子复制/删除像素列。由于概率性质,给定相同的输入,每个输出是不同的,拉伸校正不像我希望的那样均匀。注意:上面的条纹图像不是用此代码生成的
import random
import cv2
import numpy as np
def regularise_image_stretch(img: cv2.Mat, compensations: np.ndarray) -> cv2.Mat:
'''apply a non uniform stretch to an image based on an equation that maps column idx
to compression/stretch needed to make the pixel:mm ratio uniform across all cols
Args:
img (cv2.Mat): non uniform image
compensations (np.ndarray): array of compensations per column idx generated from an equation
Returns:
cv2.Mat: an image where every pixel represents 1mm
'''
def decision(val: float) -> tuple[str, bool, float]:
'''Based on the compression factor use a probabistic approach to decide
whether to insert a copy of the previous column or to delete a column.
Args:
val (float): compression value
Returns:
tuple[str, bool, float]: ("add" || "remove", should be applied, probability)
'''
addrem = "rem"
probability = 1 - val
if probability > 0:
addrem = "add"
probability = abs(probability)
return (addrem, random.random() < probability, probability)
modimg = img.copy()
res = list(map(decision, compensations))
new_img = []
previous_col = modimg[:, 0, :]
# add/replicate columns based on compression factor
for i, col in enumerate(modimg.transpose(1,0,2)):
addrem, shouldapply, _ = res[i]
new_img.append(col)
if shouldapply:
if addrem == "add":
new_img.append(previous_col)
else:
new_img.pop(-1)
previous_col = col
# as a list is being used above fix image orientation
new_img = cv2.rotate(np.array(new_img), cv2.ROTATE_90_COUNTERCLOCKWISE)
new_img = cv2.flip(np.array(new_img), 0)
new_img = cv2.resize(new_img, (img.shape[1], img.shape[0]))
return new_img
img = cv2.imread("./stripes.jpg")
new_img = regularise_image_stretch(img, compensations)
cv2.imwrite("./modifiend2.png", np.vstack([new_img, img]))
我真的很感激这方面的任何帮助:)
1条答案
按热度按时间nfeuvbwi1#
@Christoph Rackwitz你是传奇人物。多谢提醒。下面的代码运行得很好:)。下面的图片是生产线上的辊子。这些辊中的每一个具有相同的宽度。使用这个方法,我可以生成pol1d来确定正确的Map,这样所有的滚轮现在看起来都是相同的宽度,使用cv.map。