مفهوم هیستوگرام و محاسبه آن در OpenCV

در این مطلب می خواهیم یکی از مفاهیم پایه و مهم در پردازش تصویر، مفهوم هیستوگرام (Histogram) را توضیح دهیم. هیستوگرام یک نمودار (Plot) است که شدت توزیع هر یک از پیکسل ها را نشان می دهد. در نمودار هیستوگرام، عددهای محور افقی (x-axis) در حالت کلی در بازه صفر تا ۲۵۵ قرار دارند و نشان دهنده مقدار پیکسل هستند و در مقابل عددهای روی محور عمودی (y-axis) نشان دهنده تعداد هر یک از مقدار پیسکل ها هستند.

یک هیستوگرام را می توانیم هم برای تصویرهای خاکستری و هم برای تصویرهای رنگی بدست بیاوریم. توجه کنید که اگر تصویر خاکستری باشد، پس یک نمودار هیستوگرام را رسم می کنیم، زیرا تصویرهای خاکستری از نوع تک کانالی هستند و هر پیکسل از یک عدد میان بازه صفر تا ۲۵۵ تشکیل می شود.

ولی اگر  تصویر رنگی RGB باشد، پس هر پیسکل از سه رقم تشکیل شده که هر کدام میان بازه صفر تا ۲۵۵ و همچنین هر کدام بیانگر رنگ های اصلی قرمز، سبز و آبی هستند. پس در تصویرهای رنگی به ازای هر رنگ باید یک نمودار رسم کنیم. در ادامه همین مطلب به شما یاد می دهیم که چگونه توسط کتابخانه matplotlib نمودار هیستوگرام را به کمک کتابخانه OpenCV رسم کنیم.  محاسبه هیستوگرام یک تصویر بسیار مفید است زیرا توسط آن می توانیم به برخی از ویژگی های تصویر (Image Feautures)، مانند محدوده تونال (Tonal Range)، کنتراست (Contrast) و روشنایی (Bbrightness) را بدست بیاوریم.

تغییر کنتراست و روشنایی تصویر با OpenCV

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

نمودار هیستوگرام شکل زیر، تعداد پیکسل ها را برای تمامی مقدارهای پیسکل، یعنی از عدد صفر تا ۲۵۵ را نشان می دهد، پس در این حالت در محور افقی تعداد ۲۵۶ عدد (از صفر تا ۲۵۵) وجود دارداما فرض کنید می خواهید تعداد پیکسل ها را برای یک بازه از مقدار پیکسل ها نمایش دهید. به طور مثال فرض کنید می خواهید تعداد پیکسل ها را برای بازه مقدارهای بازه بندی شده 0 … 15 و 16 …31 ودر نهایت 240 … 255 نمایش دهید. بنابراین در متد ()caclHist می توانید بازه مقدارهای پیکسل را تعیین کنید. 

گام نخستمحاسبه هیستوگرام

در زبان پایتون می توانیم از متد ()calcHits از کتابخانه OpenCV و یا از متد ()histogram از کتابخانه NumPy برای محاسبه هیستوگرام تصویر استفاده کنیم. در کدهای زیر ابتدا می خواهیم توسط متد ()calcHist از کتابخانه OpenCV هیستوگرام یک تصویر خاکستری را بررسی کنیم. برای این منظور ابتدا توسط متد ()cvtColor تصویر را از فضای RGB به فضای Grayscale تبدیل و سپس ماتریس آنرا در متغیری به نام imageGray ذخیره کرده ایم.  پس از آن متغیر imageGray را به صورت براکت های باز و بسته به آرگومان اول متد ()calcHist فرستاده ایم.

آرگومان دوم نیز به صورت براکت های باز و بسته به متد فرستاده شده است و اگر تصویر خاکستری باشد، پس باید این آرگومان به صورت اندیس [0] باشد، زیرا تصویر خاکستری تنها یک کانال دارد ولی اگر تصویر رنگی باشد، اندیس صفر [0] برای رنگ آبی، اندیس یک [1] برای رنگ سبز و اندیس دو [2] برای رنگ قرمز باید فرستاده شود. به عبارت دیگر به ازای هر رنگ می خواهیم هیستوگرام آن را محاسبه کنیم.

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

آرگومان چهارم برابر با تعداد Bin است و اگر می خواهید هیستوگرام برای تمام مقدارهای پیکسل  (هر ۲۵۶ عدد) محاسبه شود، پس به صورت براکت های باز و بسته، مقدار [256] را بفرستید. آرگومان ششم نیز محدوده را نشان می دهد که با توجه به محاسبه کامل هیستوگرام، مقدار آن به صورت براکت های باز و بسته [0, 256] به آن فرستاده می شود.

محاسبه هیستوگرام توسط کتابخانه NumPy

در خط ۱۵ از کد بالا که در زیر نیز آمده است، از تابع histogram کتابخانه NumPy برای محاسبه هیستوگرام استفاده کرده ایم. سپس مطابق خط ۱۸ و ۱۹ از کد بالا، نمودار هیستوگرام را رسم کرده ایمشکل زیر محتوای دو هیستوگرام بدست آمده توسط متدهای ()calcHist و ()histogram نشان می دهد و با هم مقایسه می کند. با توجه به شکل زیر شما می توانید مفهوم و کاربرد محاسبه هیستوگرام را متوجه شوید. که در خطوط ۹ و ۱۵ به ترتیب در متغیرهای imageHistogram و hits ذخیره شده اند. توجه کنید هر دو خروجی یکی هستند ولی نمایش آنها با یکدیگر متفاوت است. توضیح کامل در خود شکل آورده شده است.

توجه کنید که کد و شکل بالا مربوط به محاسبه هیستوگرام یک تصویر خاکستری است. پیکسل های تصویر های خاکستری به صورت تک کانالی هستند و بازه مقدار هر پیکسل میان عددهای صفر تا ۲۵۵ است. در کد و شکل بالا هیستوگرام برای هر ۲۵۶ مقدار پیکسل محاسبه شده است و از این رو در نمودار هیستوگرام عددهای محور افقی از صفر تا ۲۵۵ هستند، زیرا در خود تابع ()calcHisst تاکید کرده ایم که برای تمامی مقدارها تعداد پیکسل ها را محاسبه کند. همچنین تعداد پیکسل ها روی محور عمودی نشان داده می شوند. به طور مثال در شکل زیر می توانید ببینید که تعداد پیکسل با مقدار صفر، برابر با صفر است ولی تعداد ۴۲۸۵۳ عدد پیکسل ب مقدار ۲۵۵ وجود دارد.

شکل هیستوگرام رنگی

حال می خواهیم در کد زیر هیستوگرام تصویر رنگی را ایجاد کنیم. پیش از این گفتیم که باید هیستوگرام را برای هر یک از رنگ های آبی (اندیس صفر)، رنگ سبز (اندیس یک) و رنگ قرمز (اندیس دو) محاسبه کنیم پس یک تاپل به نام colors با سه عنصر ایجاد کردیم. توجه کنید این مهم است که درون یک شرط سه گامی، اندیس های صفر، یک و دو را به متد ()calcHist بفرستیمپس در خط ۱۰ از کد زیر درگام حلقه for و به تعداد عنصرهای تاپل (سه مرتبه)، متد ()calcHist اجرا شده و متغیر اندیس درون حلقه در هر گام مقدارهای صفر، یک و دو را دریافت می کند. نهایت شکل زیر به ازای سه رنگ، هیستوگرام هر یک را ایجاد می کند.

دانلود سورس این مطلب Find and calculate histogram opencv