عملیات اصلی
عملیات محاسباتی روی تصاویر
هدف#
- یادگیری چندین عملیات محاسباتی روی تصاویر مانند جمع، تفریق، عملیات بیتی (Bitwise) و غیره.
- آشنایی با این توابع: ()cv.add، ()cv.addWeighted و غیره.
جمع تصاویر#
میتوانید دو تصویر را با تابع OpenCV به نام ()cv.add یا به سادگی با عملیات numpy یعنی res = img1 + img2 با یکدیگر جمع کنید. هر دو تصویر باید دارای عمق و نوع یکسانی باشند، یا تصویر دوم میتواند صرفاً یک مقدار اسکالر باشد.
به عنوان مثال، نمونه زیر را در نظر بگیرید:
>>> x = np.uint8([250])
>>> y = np.uint8([10])
>>> print( cv.add(x,y) ) # 250+10 = 260 => 255
[[255]]
>>> print( x+y ) # 250+10 = 260 % 256 = 4
[4]
این تفاوت زمانی که دو تصویر را با هم جمع میکنید بیشتر آشکار خواهد شد. به توابع OpenCV پایبند باشید، چرا که نتیجه بهتری ارائه خواهند داد.
ترکیب و ادغام تصویر (Image Blending)#
این کار نیز نوعی جمع تصویر است، اما به منظور ایجاد حس ترکیب یا شفافیت (Transparency)، وزنهای متفاوتی به تصاویر داده میشود. تصاویر مطابق معادله زیر با یکدیگر جمع میشوند:
با تغییر از ، میتوانید یک انتقال (Transition) زیبا بین یک تصویر به تصویر دیگر انجام دهید.
در اینجا من دو تصویر را برای ترکیب با یکدیگر در نظر گرفتم. به تصویر اول وزن 0.7 و به تصویر دوم وزن 0.3 داده شده است. تابع ()cv.addWeighted معادله زیر را روی تصویر اعمال میکند:
در اینجا برابر با صفر در نظر گرفته شده است.
img1 = cv.imread('ml.png')
img2 = cv.imread('opencv-logo.png')
assert img1 is not None, "file could not be read, check with os.path.exists()"
assert img2 is not None, "file could not be read, check with os.path.exists()"
dst = cv.addWeighted(img1,0.7,img2,0.3,0)
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()
نتیجه را در زیر بررسی کنید:

عملیات بیتی (Bitwise Operations)#
این بخش شامل عملیات بیتی AND، OR، NOT و XOR است. این عملیات در حین استخراج هر بخشی از تصویر (همانطور که در فصول بعدی خواهیم دید)، تعریف و کار با نواحی مورد نظر (ROI) غیرمستطیلی و غیره بسیار مفید خواهند بود. در زیر نمونهای از نحوه تغییر یک ناحیه خاص از تصویر را خواهیم دید.
من میخواهم لوگوی OpenCV را در بالای یک تصویر قرار دهم. اگر دو تصویر را با هم جمع کنم، رنگ تغییر خواهد کرد. اگر آنها را با هم ترکیب (Blend) کنم، یک جلوه شفاف دریافت خواهم کرد. اما من میخواهم لوگو مات (کدر یا Opaque) باشد. اگر این ناحیه مستطیلی بود، میتوانستم همانند فصل گذشته از ROI استفاده کنم؛ اما لوگوی OpenCV شکلی غیرمستطیلی دارد. بنابراین میتوانید این کار را با عملیات بیتی مطابق شکل زیر انجام دهید:
# Load two images
img1 = cv.imread('messi5.jpg')
img2 = cv.imread('opencv-logo-white.png')
assert img1 is not None, "file could not be read, check with os.path.exists()"
assert img2 is not None, "file could not be read, check with os.path.exists()"
# I want to put logo on top-left corner, So I create a ROI
rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols]
# Now create a mask of logo and create its inverse mask also
img2gray = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(img2gray, 10, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)
# Now black-out the area of logo in ROI
img1_bg = cv.bitwise_and(roi,roi,mask = mask_inv)
# Take only region of logo from logo image.
img2_fg = cv.bitwise_and(img2,img2,mask = mask)
# Put logo in ROI and modify the main image
dst = cv.add(img1_bg,img2_fg)
img1[0:rows, 0:cols ] = dst
cv.imshow('res',img1)
cv.waitKey(0)
cv.destroyAllWindows()
نتیجه را در زیر مشاهده کنید. تصویر سمت چپ ماسکی را نشان میدهد که ایجاد کردهایم. تصویر سمت راست نتیجه نهایی را نشان میدهد. برای درک بیشتر، تمام تصاویر میانی در کد بالا، به ویژه img1_bg و img2_fg را نمایش دهید.

تمرینها#
- یک اسلایدشو از تصاویر موجود در یک پوشه با انتقال نرم (Smooth Transition) بین تصاویر با استفاده از تابع cv.addWeighted ایجاد کنید.