سلام.
قرار نیست بصورت دستی مختصات رو دوباره وارد کنید. شما باید بر اساس تغییراتی که در تصویر دادید bounding boxرو هم به همون صورت تنظیم کنید. همونطور که در کامنت هم گفته شد همه انواع اگمنتیشن باعث تغییر Bounding box نمیشن. مثلا اضافه کردن نویز به تصویر شما یا اعمال تغییرات در کنتراست تصویر و... باعث جابجایی اشیا و یا بهم خوردن نسبت ها نمیشه.
مشکل البته در اعمالی مثل rotateکردن هست. که اینجا هم از قرار معلوم باید از affine transformation و فرمول های ریاضی مرتبط برای انجام تبدیلات استفاده بشه. ولی طی تحقیقات مختصر من ، ساده ترین کار شاید استفاده از کتابخونه shapely پایتون باشه.
به اینصورت که شما ابتدا یه polygon یا راحت تر یه box ایجاد میکنید به اندازه bounding boxمورد نظر خودتون و بعد ترنسفورمیشن مورد نظر خودتون رو اعمال میکنید. و در آخر هم مختصات جدید رو استفاده میکنید.
برای شروع میتونید از کد زیر استفاده کنید :
from matplotlib import pyplot
from shapely.geometry import Polygon
from descartes.patch import PolygonPatch
from shapely.geometry import box
from shapely import affinity
fig = pyplot.figure(1, dpi=90)
ax = fig.add_subplot(121)
b = box(2, 4, 11, 8)
rotated_i = affinity.rotate(b, 45, origin=(10,10))
#flip horizontally
flipped_h = affinity.scale(b, xfact=-1.0, origin=(10,10))
#flip vertically
flipped_v = affinity.scale(b, yfact=-1.0, origin=(10,10))
patch_orig = PolygonPatch(b, facecolor='blue', edgecolor='black', alpha=0.5, zorder=1)
patch_rotated = PolygonPatch(rotated_i, facecolor='red', edgecolor='black', alpha=0.5, zorder=1)
patch_flip_h = PolygonPatch(flipped_h, facecolor='green', edgecolor='black', alpha=0.5, zorder=1)
patch_flip_v = PolygonPatch(flipped_v, facecolor='black', edgecolor='white', alpha=0.5, zorder=1)
ax.add_patch(patch_orig)
ax.add_patch(patch_rotated)
ax.add_patch(patch_flip_h)
ax.add_patch(patch_flip_v)
ax.set_title('result')
xrange = [0, 20]
yrange = [0, 20]
ax.set_xlim(*xrange)
ax.set_xticks(list(range(*xrange)) + [xrange[-1]])
ax.set_ylim(*yrange)
ax.set_yticks(list(range(*yrange)) + [yrange[-1]])
ax.set_aspect(1)
pyplot.show()
خروجی کد بالا بشکل زیر هست(شکل اصلی مستطیل آبی رنگ هست که به صورت عمودی و افقی و 45 درجه روتیت شده) :
کد رو میتونید از اینجا بصورت آنلاین اجرا کنید (با VPN فقط چک کنید)
چیزی که شما نیاز دارید (قبلش اون لینکی که به shapely دادم رو مطالعه کنید) این بخش زیر هست :
b = box(2, 4, 11, 8)
rotated_i = affinity.rotate(b, 45, origin=(10,10))
#flip horizontally
flipped_h = affinity.scale(b, xfact=-1.0, origin=(10,10))
#flip vertically
flipped_v = affinity.scale(b, yfact=-1.0, origin=(10,10))
توضیحات :
خط اول نمایانگر bbox شماست که مختصاتش رو وارد میکنید. و دستورات بعدی هم همونطور که میبینید برای روتیت کردن هست به شیوه های مختلف(برای تست و مشاهده اینکه خروجی به چه شکل در میاد). دقت کنید که اگه اون origin رو بردارید بصورت دیفالت بر اساس محور خود شی عمل روتیت انجام میشه(center). چیزی که شما نیاز دارید اینه که این تغییر حول محور تصویر انجام بشه (مرکز تصویر). پس در اون origin وسط تصویر (یا کلا هر محوری که دوست دارید حول اون روتیت انجام بشه) رو مشخص میکنید.
من برای اینکه مشخص باشه تغییرات به چه صورتی هست از matplotlib به این صورت استفاده کردم .
فرض کردم تصویر ما ۲۰ در ۲۰ هست (در نمودار میبینید که xrange و yrange بین ۰ تا ۲۰ هست) تا اینطور حرکت و تغییرات مشخص باشن .
حالا دوتا نکته باقی میمونه :
نکته اول اینکه برای flip کردن عمودی و افقی راه های مختلفی وجود داره ولی باز ساده ترین شیوه استفاده از همین scale موجود در shapely هست که من کامنت کردم (تو خود مستندات اون بخش انتهایی هم البته هست بخونید مشخصه ).
نکته دوم هم بر میگیرده به دریافت مختصات نهایی بعد از اعمال تبدیلات برای اینکار از پراپرتی .bounds
استفاده میکنید. یعنی خیلی راحت میزنید flipped_h.bounds
و مختصات رو به فرم یه (minx, miny, maxx, maxy) tuple دریافت میکنید که این هم البته توضیحاتش در مستندات هست.
نکته اخر هم اینه وقتی مختصات منفی گرفتید یعنی خارج از تصویر شماست و میتونید بجای اونها ۰ قرار بدید یا هر تصمیمی که فکر میکنید صحیحه انجام بدید.