عکاسی محاسباتی
تصحیح انحراف رنگی (Chromatic Aberration Correction)
هدف#
در این فصل، یاد خواهیم گرفت چگونه:
-
دوربین خود را کالیبره کرده و ضرایب مربوط به تصحیح انحراف رنگی جانبی (Lateral Chromatic Aberration) را به دست آوریم.
-
این ضرایب را که عدم انطباق کانالهای قرمز/آبی را مدلسازی میکنند صادر (Export) کنیم.
-
تصاویر را با استفاده از توابع درون OpenCV تصحیح نماییم.
مفاهیم پایه#
انحراف رنگی جانبی زمانی اتفاق میافتد که طول موجهای مختلف در موقعیتهای تصویر با اندکی تفاوت متمرکز میشوند. این پدیده منجر به ایجاد هالههای قرمز/آبی در لبههای با کنتراست بالا میشود و به ویژه در دوربینها و لنزهای قدیمی یا با کیفیت پایینتر رایج است. این یک ویژگی فیزیکی لنز است و به طور مداوم در هر تصویری که با آن دوربین و لنز گرفته میشود ظاهر میگردد.

اعتبار تصویر: PawełS, CC BY-SA 3.0 http://creativecommons.org/licenses/by-sa/3.0/, via Wikimedia Commons
ما انحراف رنگی جانبی را به عنوان یک اعوجاج هندسی در کانالهای قرمز و آبی نسبت به کانال مرجع سبز در نظر میگیریم و هدفمان تخمین نگاشتی است که کانالهای قرمز و آبی را با سبز همتراز کند.
این تصحیح بر اساس مقاله روداکووا و همکاران (Rudakova et al.) در زمینه انحراف رنگی جانبی است. عدم انطباق در هر کانال به عنوان یک چندجملهای با درجهای مشخص مدل میشود. فاصله بین مکانهای دقیق مراکز در کانالهای قرمز/آبی و کانالهای سبز با پیچش و انتقال (Warp) این مراکز به حداقل میرسد.
این مقاله همچنین استفاده از الگوی کالیبراسیون دیسکهای سیاه را پیشنهاد کرده است؛ تعدادی بسیار بیشتر از تعداد ضرایب مدل چندجملهای برای دستیابی به برازش مناسب. معمولاً از درجه ۱۱ استفاده میشود، اما درجات کوچکتر میتوانند با عملکرد و سرعت بسیار بهتر به سطح مشابهی از دقت دست یابند.

کالیبراسیون#
برای ایجاد مدلی از عدم انطباق کانالها، از روند کالیبراسیون زیر استفاده میکنیم:
-
عکس کالیبراسیون موجود در opencv_extra/testdata/cv/cameracalibration/chromatic_aberration/chromatic_aberration_pattern_a3.png را چاپ کنید. این عکس شبکهای از دیسکهای سیاه روی پسزمینه سفید است و از آنجا که حاشیههای انحراف رنگی در لبههای اشیاء در عکس ظاهر میشوند، ما قادر خواهیم بود بسیاری از عدم انطباقهای مختلف را مشاهده کرده و آنها را به طور دقیق مدلسازی کنیم.
-
با استفاده از دوربین خود یک یا چند تصویر از شبکه کالیبراسیون چاپشده بگیرید. اطمینان حاصل کنید که تمام دیسکها در عکس باشند و شبکه تا حد امکان فضای تصویر را پر کند، زیرا انحراف رنگی در لبهها و گوشههای عکس در شدیدترین حالت خود است. شما باید بتوانید حاشیههای رنگی را با چشم مشاهده کنید.
-
کالیبراسیون را اجرا کنید؛ به chromatic_calibration.py مراجعه نمایید. این برنامه کاربردی میتواند به شرح زیر استفاده شود:
chromatic_calibration.py calibrate [-h] [--degree DEGREE] --coeffs_file YAML image
chromatic_calibration.py correct [-h] --coeffs_file YAML [-o OUTPUT] image
chromatic_calibration.py full [-h] [--degree DEGREE] --coeffs_file YAML [-o OUTPUT] image
chromatic_calibration.py scan [-h] --degree_range k0 k1 image
فرمان Calibrate ضرایب چندجملهای را تخمین میزند و آنها را در یک فایل YAML برای استفاده در توابع تصحیح خروجی میدهد:
- کانالهای BGR را تفکیک میکند، مراکز دیسک را در هر کانال با دقت زیرپیکسلی (Sub-pixel Precision) پیدا میکند.
- مراکز را از طریق KD-tree با رنگ سبز جفت میکند.
- جملات تکجملهای را تا
--degreeمیسازد و کمترین مربعات را حل میکند، سپس با الگوریتم بهینهسازی دیگری آن را بهبود میبخشد. - یک فایل YAML را با مشخصات زیر ذخیره میکند:
image_widthوimage_heightred_channel/blue_channel: ضرایبcoeffs_xوcoeffs_y(طول )، و باقیماندههایrms.
فرمان Scan بازه درجه چندجملهای را جاروب کرده و کیفیت را مقایسه میکند. اگرچه درجات بالاتر تقریباً همیشه انحراف را بهتر مدل میکنند، درجات پایینتر میتوانند بسیار سریعتر باشند:
- کالیبراسیون را برای هر درجه در بازه k0 تا k1 برای برازش مدلها در هر درجه اجرا میکند.
- کانتورهای کامل دیسک را در هر کانال استخراج میکند.
- کانتورهای R/B را با استفاده از چندجملهایهای هر درجه به سمت G تاب میدهد (Warp) و فواصل نزدیکترین همسایه را اندازه میگیرد.
- جدولی از فواصل بیشینه / میانگین / انحراف معیار (بر حسب پیکسل) برای قرمز و آبی چاپ میکند.
- کاربر سپس میتواند انتخاب کند چه درجهای بهترین عملکرد را دارد و دوربین را با آن درجه خاص کالیبره کند.
کد#
نمونه کد مینیمال پایتون برای تصحیح انحراف رنگی:
import cv2 as cv
INPUT = "path/to/input.jpg"
CALIB_YAML = "path/to/ca_photo_calib.yaml"
OUTPUT = "corrected.png"
BAYER = -1
SHOW = True
FileStorage fs(parsed_args.coeffs_file, FileStorage::READ);
coeffMat, calib_size, degree = cv2.loadChromaticAberrationParams(fs.root())
corrected = cv.correctChromaticAberration(img, coeffMat, calib_size, degree, BAYER)
if SHOW:
cv.namedWindow("Original", cv.WINDOW_AUTOSIZE)
cv.namedWindow("Corrected", cv.WINDOW_AUTOSIZE)
cv.imshow("Original", img)
cv.imshow("Corrected", corrected)
print("Press any key to close...")
cv.waitKey(0)
cv.destroyAllWindows()
cv.imwrite(OUTPUT, corrected)
منابع اضافی#
[rudakova2013precise]