هیستوگرام در پردازش تصویر

۱- نمودار هیستوگرام چیست؟
۱-۲- هیستوگرام برای تصاویر رنگی
۱-۳- متعادل سازی هیستوگرام


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

باید گفت که  شفافیت یک عکس، کار کنتراست است که یکی از کاربردهای هیستگرام است. از طرفی کنتراست، بر تفاوت  بین سیاهترین(تعداد   پیکسل ها به سمت ۰) و روشنترین( تعداد پیکسل ها به سمت ۲۵۵) قسمت های یک عکس تاثیر میگذارد.

بالا بودن کنتراست نشان از کیفیت تصویر است. یعنی ما هم روشنایی ها را داریم و هم تاریکی ها را داریم. یک جورایی نمودار ما پهن میباشد . ولی در کنتراست پایین که وضوح عکس پایین میاد، نمودار باریک است. در اینجا جزئیات کمتری داریم.

و درک این مسئله با نمودار هیستوگرام بسیار آسانتر خواهد بود.

 نمودار هیستوگرام چیست؟

 هیستوگرام یا بافت‌نگار،  به زبان خیلی ساده به نموداری گفته می‌شود که  به ما بگوید به عنوان مثال  چند تا عدد ۹ داریم . عدد ۹ که روی محور x قرار میگیرد و اگر تعداد آن ۱۸ باشد با محور y  مشخص میشود.

تصویر زیر یک ماتریس دو بعدی از یک تصویر است که که حاوی اطلاعات از شدت روشنایی است .اگر فرض کنیم، تعداد پیکسلهایی که شدت روشنایی مثلا ۰ دارند ۱۰ تا است، ۱۰ را در محور y و محدوده شدت روشنایی(۰ یا سیاه) را درمحور x نشان میدهد.
یک هیستوگرام  مجموعه ای از مناطق مستطیل شکل یا استوانه ای به نام سطل(bin) است. (تعریف دیگر)

هیستوگرام 

https://docs.opencv.org

اگر بخواهیم این داده ها را به صورت سازمان یافته ببینیم  باید چه کنیم؟ با توجه به اینکه محدوده ارزش اطلاعات برای این مورد ۲۵۶ مقدار است، میتوانیم محدوده را به بخشهایی مثل سطل(bins) تقسیم کنیم:

\begin{array}{l} [0, 255] = { [0, 15] \cup [16, 31] \cup ....\cup [240,255] } \\ range = { bin_{1} \cup bin_{2} \cup ....\cup bin_{n = 15} } \end{array}

بنابراین  می توانیم تعداد پیکسل هایی را که در محدوده هر سطل قرار می گیرند، نگهداریم. برای تصویر بالا، تصویر زیر آماده شده است. محور x همان سطل ها و محور y تعداد پیکسل.

هیستوگرام در پردازش تصویر

Histogram

این یک مثال ساده از نحوه عملکرد هیستوگرام و دلیل مفید بودن آن است. هیستوگرام می تواند نه تنها از شدت های رنگ،  بلکه از ویژگی های تصویری که می خواهیم اندازه گیری کنیم (مانند شیب، جهت ها و غیره) باشد. 

بیایید برخی ورودی های تابع  هیستوگرام را شناسایی کنیم:

  • dims: تعداد پارامترهایی که می خواهید اطلاعات را جمع آوری کنید. در مثال ما مقدار این پارامتر ۱ است. چون فقط مقدار شدت روشنایی را در نظر گرفتیم. 
  • bins : تعداد هر مستطیل یا سطل را مشخص میکند. در این مثال bins = 16
  • range: بازه ای از مقادیر [range = [0,255

اگر می خواهید دو ویژگی را حساب کنید چه؟ در این حالت نتیجه شما یک قطعه ۳D است. همین کار را برای ویژگی های بیشتر اعمال می کند (مطمئنا پیچیده تر می شود).

در تمام قسمت ها از تصویر زیر به عنوان ورودی استفاده شده است:

Histogram

تصویر اصلی

import cv2
import numpy as np
from matplotlib import pyplot as plt

gray_img = cv2.imread('images_histogram.png', cv2.IMREAD_GRAYSCALE)#histogram tasvir tak kanale
cv2.imshow('GoldenGate',gray_img)
hist = cv2.calcHist([gray_img],[0],None,[256],[0,256])
plt.hist(gray_img.ravel(),256,[0,256])
plt.title('Histogram for gray scale picture')
plt.show()

while True:
k = cv2.waitKey(0) & 0xFF
if k == 27: break             # ESC key to exit
cv2.destroyAllWindows()

hisgray

image_histogram

image_histogram

نکته: نحوه کارکرد تابع ()ravel, همانند (reshape(-1.

 import numpy as np
x = np.array([[1, 2, 3], [4, 5, 6]])
print (np.ravel(x))
[1 2 3 4 5 6]
x.reshape(-1)
array([1, 2, 3, 4, 5, 6])

()calcHist

OpenCV از  تابع ()cv2.calcHist  برای هیستوگرام استفاده میکند. بنابراین، زمان آن است که به پارامترهای خاص مربوط به تابع () cv2.calcHist نگاه کنیم:

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])

ما به صورت زیر استفاده کردیم:

hist = cv2.calcHist([gray_img],[0],None,[256],[0,256])

پارامتر ها

  1. images: تصویر منبع از نوع uint8 یا float32، باید به عنوان یک لیست ارائه شود. [gray_img]
  2. channels: این مورد نیز به عنوان یک لیست [] داده شده است. این شاخص کانال است که ما با آن هیستوگرام را محاسبه می کنیم. برای مثال، اگر ورودی تصویر سیاه و سفید است، مقدار آن [۰] است. برای تصویر رنگی، می توانید [۰]، [۱] یا [۲] را به ترتیب برای هیستوگرام کانال آبی، سبز یا قرمز محاسبه کنید.
  3. mask:  برای پیدا کردن هیستوگرام  تصویرکامل ، آن را به عنوان None تنظیم شده است. با این حال، اگر ما می خواهیم هیستوگرام منطقه خاص تصویر را دریافت کنیم، باید یک تصویر ماسک برای آن ایجاد کنیم و آن را ماسک کنیم.
  4. histSize:  نشان دهنده شمارش BIN است. باید در [] داده شود. برای مقیاس کامل، ما [۲۵۶]را قرار دادیم .
  5. ranges : به طور معمول، [۰،۲۵۶] است.

()NumPy – np.histogram

همچنین NumPy یک تابع برای هیستوگرام، که ()np.histogram  است  را فراهم می کند. بنابراین، ما می توانیم به جای تابع OpenCV از NumPy استفاده کنیم:

import cv2
import numpy as np
from matplotlib import pyplot as plt

gray_img = cv2.imread('hisimage.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('GoldenGate',gray_img)
#hist = cv2.calcHist([gray_img],[0],None,[256],[0,256])
hist,bins = np.histogram(gray_img,256,[0,256])

plt.hist(gray_img.ravel(),256,[0,256])
plt.title('Histogram for gray scale picture')
plt.show()

while True:
k = cv2.waitKey(0) & 0xFF
if k == 27: break             # ESC key to exit
cv2.destroyAllWindows()

هیستوگرام برای تصاویر رنگی

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('images/GoldenGateSunset.png', -1)
cv2.imshow('GoldenGate',img)

color = ('b','g','r')
for channel,col in enumerate(color):
histr = cv2.calcHist([img],[channel],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.title('Histogram for color scale picture')
plt.show()

while True:
k = cv2.waitKey(0) & 0xFF
if k == 27: break             # ESC key to exit
cv2.destroyAllWindows()
his-color-image

هیستوگرام برای تصاویر رنگی


متعادل سازی هیستوگرام

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

یک تصویر را که مقادیر پیکسل(شدت روشنایی) آن،  به رنج کمی از مقادیر،  محدود است را در نظر بگیرید. برای مثال، تصویر روشن تر تمام پیکسل ها را به مقادیر بالا(نزدیک به ۲۵۵) محدود خواهد کرد. اما یک تصویر خوب، پیکسل ها را از تمام نقاط تصویر انتخاب میکند.

بنابراین باید این هیستوگرام را به هر دو انتها ببرید ( تصویر زیر از ویکیپدیا داده شده است) و این همان کاری است که متعادل سازی  هیستوگرام می کند (به صورت ساده).

این عمل، کنتراست تصویر را بهبود می بخشد. 

histogram_equalization

متعادل سازی هیستوگرام

importcv2
import numpy as  np
from matplotlib import pyplot as plt
img = cv2.imread('wiki.jpg',0)
hist,bins = np.histogram(img.flatten(),256,[0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'b')
plt.hist(img.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()

در تصویر، مقدار میانگین مقدار متوسط شدت روشنایی تصویر را نشان می دهد و مقدار واریانس، مقدار متوسط کنتراست تصویر را نمایش می دهد.

 🆔@image_Process
🌐https://t.me/image_Process


دیدگاهتان را بنویسید

We are glad you have chosen to leave a comment. Please keep in mind that comments are moderated according to our comment policy.