اهداف

  • دسترسی به پیکسل های عکس و ویرایش آنها
  • دسترسی به تنظیمات عکس
  • جداسازی و ترکیب عکس ها
  • تنظیم ناحیه علاقه

اکثر کد های این قسمت numpy هستند و دانش مناسب شما ازاین کتابخانه میتونه به بهینه سازی کد شما کمک کنه.

دسترسی و تغییر دادن پیکسل

>>> import numpy as np
>>> import cv2 as cv
 
>>> img = cv.imread('messi5.jpg')
>>> assert img is not None, "file could not be read, check with os.path.exists()"

شما میتوانید با استفاده از سطر و ستون یک پیکسل به اون دسترسی داشته باشید برای RGB یک ارایه به ما برگردونده میشه.

>>> px = img[100,100]
>>> print( px )
[157 166 200]
 
# accessing only blue pixel
>>> blue = img[100,100,0]
>>> print( blue )
157 

همینطوری هم میتوند مغادیر پیکسل رو ویرایش کنید


>>> img[100,100] = [255,255,255]
>>> print( img[100,100] )
[255 255 255]

دسترسی به تنظیمات عکس

تنظیمات عکس شامل تعداد سطر و ستون های عکس , تعداد کانال های یک عکس و تعداد پیکسل و .... میشه. img.shape یک عکس یک تاپل شامل تعداد سطر و ستون و کانال های عکس میشه

  • نکته : در عکس های سفید سیاه تاپل برگردانده شده برای تنظیمات فقط شامل سطر و ستون میشه , این روش خوبی برای تشخیص عکس سفید سیاه از رنگی است.

تعداد کل پیکسل ها با دستور img.size قابل دسترسی است

>>> print( img.size )
562248

datatype یک عکس با دستور img.dtype قابل دسترسی است

>>> print( img.dtype )
uint8

ناحیه مورد علاقه

در مبحث تشخیص اشیا در عکس به عنوان مثال چشم انسان , ابتدا صورت پیدا میشود و سپس در ناحیه صورت به دنبال چشم میگردیم این یکی از کاربرد های ناحیه علاقه است. در اصل به جای گشتن کل عکس , ناحیه کوچک تری را میگردیم که باعث سریع تر شدن فرایند میشود. در مثال زیر توپ رو کپی میکنم

>>> ball = img[280:340, 330:390]
>>> img[273:333, 100:160] = ball

image

جداسازی و ترکیب کانال های عکس

در بعضی مواقع ممکن است نیاز باشه به صورت جداگانه روی کانال های آبی سبز و قرمز کار کنیم در اینجوری مواقع از دستور زیر برای جداسازی کانال ها استفاده میکنیم در بعضی مواقع هم شاید نیاز باشه کانال هایی رو ترکیب کنیم

>>> b,g,r = cv.split(img)
>>> img = cv.merge((b,g,r))

با دستور اولی جدا سازی انجام میشه و با دستور دومی ترکیب

یا

>>> b = img[:,:,0]

فرض کنید میخواهیم همه پیکسل های قرمز رو به صفر تغییر دهیم

>>> img[:,:,2] = 0
  • توجه کنید دستور cv.split() زمان زیادی برای اجرا نیاز داره , بهتره فقط درموارد ضروری استفاده بشه

ساخت قاب برای عکس

برای ساخت قاب اطراف عکس از دستور cv.copyMakeBorder() استفاده میشه این تابع ورودی های زیر را میگیرد:

src : عکس ورودی

top, bottom, left, right - عرض حاشیه برحسب پیکسل در جهات گفته شده

borderType - علامتی برای تعریف نوع قاب و میتونه مغادیر زیر رو داشته باشه

  • cv.BORDER_CONSTANT - با یک رنگ ثابت قاب رو میسازه
  • cv.BORDER_REFLECT - قاب انعکاس عناصر قاب خواهد بود مانند : fedcba|abcdefgh|hgfedcb
  • cv.BORDER_REFLECT_101 or cv.BORDER_DEFAULT - مثل بالا اما با یک تغییر جزیی : gfedcb|abcdefgh|gfedcba
  • cv.BORDER_REPLICATE - عنصر آخر در سراسر قاب تکرار میشه : aaaaaa|abcdefgh|hhhhhhh
  • cv.BORDER_WRAP - نمیشه توضیح داد , یه همچین چیزی میشه : cdefgh|abcdefgh|abcdefg

value : رنگ قاب اگر نوع قاب cv.BORDER_CONSTANT باشد

کد زیر یک مثال از همه انواع قاب های گفته شده هست

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
 
BLUE = [255,0,0]
 
img1 = cv.imread('opencv-logo.png')
assert img1 is not None, "file could not be read, check with os.path.exists()"
 
replicate = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REPLICATE)
reflect = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT)
reflect101 = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT_101)
wrap = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_WRAP)
constant= cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_CONSTANT,value=BLUE)
 
plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
 
plt.show()

image