[英]Find new (X,Y) after resizing and cropping image
I have a image that has to be cropped around a bounding box and resized to 256x256.我有一个必须围绕边界框裁剪并调整为 256x256 的图像。 In my original image I have an number of Points (x,y) that are in the bounding box.
在我的原始图像中,我在边界框中有许多点 (x,y)。
This is my original image with my original coordinates marked:这是我的原始图像,标有我的原始坐标:
Heres the cropped result, where the red points are the right x,y and the blue ones are my current result:这是裁剪后的结果,其中红色点是正确的 x,y,蓝色点是我当前的结果:
Heres how I'm doing it:这是我的做法:
import numpy as np
import cv2
def scaleBB(bb, scale):
centerX = (bb[0][0] + bb[1][0]) / 2
centerY = (bb[0][1] + bb[2][1]) / 2
center = (centerX, centerY)
scl_center = (centerX * scale[0], centerY * scale[1])
p1 = scale * (bb[0] - center) + scl_center
p2 = scale * (bb[1] - center) + scl_center
p3 = scale * (bb[2] - center) + scl_center
p4 = scale * (bb[3] - center) + scl_center
return np.array([p1, p2, p3, p4])
def expandBB(scaledBB, size):
bbw = np.abs(scaledBB[0][0] - scaledBB[1][0])
bbh = np.abs(scaledBB[0][1] - scaledBB[2][1])
expandX = (size[0] - bbw) / 2
expandY = (size[1] - bbh) / 2
p1 = scaledBB[0] + (-expandX, -expandY)
p2 = scaledBB[1] + (+expandX, -expandY)
p3 = scaledBB[2] + (+expandX, +expandY)
p4 = scaledBB[3] + (+expandX, +expandY)
return np.array([p1, p2, p3, p4])
def recalculate_joints_points(oldX, oldY, newX, newY, joints):
R_x = newX / oldX
R_y = newY / oldY
new_joints = []
for index, joint in enumerate(joints):
x = joint[0]
y = joint[1]
n_x = round(R_x * x)
n_y = round(R_y * y)
print(R_x, R_y, x, y, n_x, n_y)
new_joints.append([n_x, n_y])
return np.array(new_joints)
def cropAndResizeImage(label, bb):
img_path = "original.jpg"
# downscale
image = cv2.imread(img_path)
# orgSize = image.shape[:2]
label = label
bb = bb
print(bb)
dim = int(256 / 2)
# define the target height of the bounding box
targetHeight = 200.0
w = np.abs(bb[0][0] - bb[1][0])
h = np.abs(bb[0][1] - bb[2][1])
targetScale = targetHeight / h
print(targetScale)
scaledImage = cv2.resize(image, (0, 0), fx=targetScale, fy=targetScale)
scaledBB = scaleBB(bb, (targetScale, targetScale))
cropRegion = expandBB(scaledBB, (256, 256))
print(scaledBB)
print(cropRegion)
startX = int(cropRegion[0][0] + dim)
startY = int(cropRegion[0][1] + dim)
endX = startX + 256 # cropRegion[2][0] + dim
endY = startY + 256 #cropRegion[2][1] + dim
print(startX, startY, endX, endY)
padded_image = np.pad(scaledImage, ((dim, dim), (dim, dim), (0, 0)), mode='constant')
croppedImage = padded_image[startY:endY, startX:endX]
# new label
print(image.shape, croppedImage.shape)
oldWidth = image.shape[1]
oldHeight = image.shape[0]
newWidth = 256 + dim
newHeight = 256 + dim
out_label = recalculate_joints_points(oldWidth, oldHeight, newWidth, newHeight, label)
return [croppedImage, out_label]
def main():
labels = np.array([[1214, 598],
[1169, 424],
[1238, 273],
[1267, 285],
[1212, 453],
[1229, 622],
[1253, 279],
[1173, 114],
[1171, 113],
[1050, 60],
[1106, 143],
[1140, 100],
[1169, 80],
[1176, 148],
[1152, 280],
[1087, 391]])
bb = np.array([[1050, 60],
[1267, 60],
[1267, 622],
[1050, 622]])
img, label = cropAndResizeImage(labels, bb)
for point in label:
print(point)
x,y = point
cv2.circle(img,(int(x),int(y)),5,(255,0,0),-11)
cv2.imshow("cropped", img)
cv2.waitKey()
if __name__ == '__main__':
main()
As far as I understood is to get the new (x,y) you have to calculate the ratio (difference of size in a scale factor) but it still seems off.据我所知,要获得新的 (x,y),您必须计算比率(比例因子中的大小差异),但它似乎仍然存在。 Any help is appreciated.
任何帮助表示赞赏。
EDIT 1:编辑 1:
Using as newHeight/Width just 256 produces this image:使用 newHeight/Width 仅 256 生成此图像:
*EDIT 2: *编辑2:
Using solution of @ChrisH its quite perfect but still a little bit off:使用@ChrisH 的解决方案非常完美,但仍有一点点:
Here is a function that will translate directly from the original coordinates into the cropped and scaled coordinates.这是一个函数,它将直接从原始坐标转换为裁剪和缩放的坐标。 You can skip all the other functions and transform points directly with this
您可以跳过所有其他功能并直接使用此转换点
def getNewCoords(x,y):
bbUpperLeftX = bb[0][0]
bbUpperLeftY = bb[0][1]
bbLowerRightX = bb[2][0]
bbLowerRightY = bb[2][1]
sizeX = bbLowerRightX - bbUpperLeftX
sizeY = bbLowerRightY - bbUpperLeftY
sizeMax = max(sizeX, sizeY)
centerX = (bbLowerRightX + bbUpperLeftX)/2
centerY = (bbLowerRightY + bbUpperLeftY)/2
offsetX = (centerX-sizeMax/2)*256/sizeMax
offsetY = (centerY-sizeMax/2)*256/sizeMax
x = x * 256/sizeMax - offsetX
y = y * 256/sizeMax - offsetY
return (x,y)
Since you define既然你定义
endX = startX + 256
endY = startY + 256
And make the output image as并使输出图像为
croppedImage = padded_image[startY:endY, startX:endX]
Shouldn't the new width and height be 256?新的宽度和高度不应该是 256 吗? instead you define them as
相反,您将它们定义为
newWidth = 256 + dim
newHeight = 256 + dim
I think dim
is unnecessary here我认为这里不需要
dim
You can use augmentit to do the task.您可以使用Augmentit来完成任务。
pip install augmentit
Documentation link : https://github.com/sandesha-hegde/augmentit文档链接: https : //github.com/sandesha-hegde/augmentit
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.