بهبود تصاویر با افزایش کنتراست

افزایش کنتراست

افزایش کنتراست با یکنواخت سازی هیستوگرام

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

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

فرض کنید یک تصویر خاکستری با مقادیر سطوح روشنایی r در بازه [۰,۱] وجود داشته باشد، یک تابع تبدیل مانند T بر روی این تصویر بصورت (s=T(r قابل تعریف است.

به منظور یکنواخت سازی هیستوگرام، تبدیلی مانند T باید دارای دو خاصیت باشد:

  • این تابع تبدیل بصورت یکنوا صعودی باشد
  • بازای r در بازه [۰,۱] مقادیر T(r) نیز در بازه [۰,۱] قرار گیرند.

این شروط تضمین میکنند که دامنه خروجی با ورودی یکی باشد، و همچنین نگاشتی یک به یک باشد و مانع ایجاد ابهام شود.

یک ایده برای تابع تبدیل (s=T(r با فرض پیوسته در نظر گرفتن تابع توزیع احتمال که خروجی یکنواخت تولید کند استفاده از رابطه زیر است.

 

فرمول 1

با توجه به تابع یکنواخت ساز فوق و در نظر گرفتن هیستوگرام نرمال شده تصویر در حالت گسسته میتوان تابع تبدیلی که هیستوگرام را یکنواخت کند به شکل زیر بیان کرد:

فرمول 2

که در آن MN تعداد کل پیکسلها در تصویر، nk تعداد پیکسلهایی که شدت روشنایی rk دارند و L تعداد سطوح ممکن شدت روشنایی در تصویر است. در واقع ابتدا باید هیستوگرام نرمال شده و سپس هیستوگرام تجمعی تصویر ورودی را محاسبه نمود و نهایتا اعداد را به بازه [۰,L-1] انتقال داد و با نگاشت هر پیکسل در تصویر ورودی با شدت روشنایی rk به یک پیکسل متناظر با شدت روشنایی sk تصویر خروجی که دارای هیستوگرامی متعادلتر شده است را بدست آورد.

بعنوان نمونه نتیجه این عملیات را در تصویر زیر میبینید که تصویر ورودی اولیه دارای هیستوگرامی با مقادیری در محدوده خاص و بصورت نا یکنواخت است در حالی که هیستوگرام تصویر حاصل نسبتا یکنواخت تر است و نتیجه کار بهبود کنتراست و بهبود جلوه بصری در تصویر خروجی است

effect of histogram

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

منبع


بهبود کنتراست تصاویر رقومی

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

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

 همانطور که میدانید ارزش ثبت شده برای هر پیکسل در یک باند از تصویر ماهواره ای، بین اعداد صفر و ۲۵۵ متغیر است. هرچه به سمت صفر میرویم تصویر تیره تر شده و هر چه به سمت ۲۵۵ حرکت میکنیم پیکسل ما روشن تر دیده میشود. در تصاویری که کنتراست پایین تری دارند، بیشتر پیکسلها دارای مقادیری از ارزش هستند که محدوده کوچکی را به خود اختصاص داده است. مثلاً اکثر پیکسلها مقادیری بین ۵۰ تا ۱۰۰ دارند. در اینحالت بخشهایی از محدوده ۲۵۰ واحدی ما خالی میماند و عوارض اختلاف رنگ کمتری خواهند داشت.

Low Contrast Image
تصویر با کنتراست پایین

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

 برای بهبود کنتراست تصاویر به روشهای مختلفی میتوانیم فضای موجود بین ارزش صفر تا ۲۵۵ را بین پیکسلها تقسیم نماییم. مثلاً فرض میکنیم در یکی از باندهای تصویر ما مینیمم و ماکزیمم ارزشها ۵۰ و ۱۰۰ باشد. اگر بخواهیم مینیمم را بر روی صفر قرار داده و ماکزیمم بر روی ۲۵۰ قرار گیرد، درواقع تصویری ایجاد کرده ایم که در آن فاصله بین ارزش پیکسلها ۵ برابر شده است. در اینحالت اگر بین دو پیکسل یک واحد اختلاف ارزش وجود داشته باشد، این یک واحد اختلاف به ۵ واحد افزایش خواهد یافت. مسلماً تمایز بین دو پیکسل با ارزشهای متوالی بسیار سخت تر از تمایز بین دو پیکسلی خواهد بود که ۵ واحد با یکدیگر اختلاف دارند. این اختلاف در کل تصویر تسری پیدا نموده و درنهایت باعث افزایش قدرت تمایز عوارض خواهد شد.

High Contrast Image
بهبود کنتراست تصاویر باعث تمایز بیشتر عوارض می گردد.

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

پیشنهاد بعدی   شبکه نامنظم مثلثی (TIN) ، کاربردها و نحوه ایجاد آن در نرم‌افزار ArcGIS

 درحقیقت نوعی کلاسه بندی یا همان Classification برای مقادیر ارزش پیکسلها در نظر گرفته شده است و کلیه مقادیر در کلاسهایی که از صفر شروع شده و به ۲۵۵ ختم میشوند افراز شده اند. روشهای مختلفی برای نحوه کلاسه بندی ارزشها وجود دارد که برخی از آنها مبتنی بر محاسبه پارامترهای آماری هستند. روشهای مختلفی چون  Minimum-Maximum ، Standard Deviations ، Histogram Specification ، Histogram Equalize و Percent Clip نمونه هایی از روشهای کلاسه بندی هستند که در نرم افزار ArcGIS برای بهبود کنتراست تصاویر در نظر گرفته شده اند.

کافیست تا یک نمونه از فایل رستری را در نرم افزار ArcGIS باز کرده و در پنجره Layer Properties و در سربرگ Symbology ، حالت نمایش را در حالت Stretched قرار دهید و سپس در بخش Stretch گزینه Type را تغییر دهید تا اثر تغییر روش کلاسه بندی را در نمایش فایل رستری خود مشاهده نمایید.

منبع


افزایش کنتراست یک تصویر با دستور histeq در متلب

دستور histeq در متلب، برای افزایش کنتراست یک تصویر به کار می رود. چنانچه مقادیر مربوط به رنگ های به کار رفته در یک تصویر را مشاهده کنیم (این کار با دستور imhist در متلب، امکان پذیر می باشد)، آنگاه ممکن است که بخشی از رنگ ها، به مقدار زیاد، در تصویر به کار رفته باشند و بخشی دیگر، کمتر در تصویر باشند. افزایش کنتراست، باعث می شود که میزان به کار رفتن رنگ های مختلف، به هم نزدیکتر شود و دیگر تفاوت زیادی که ذکر شد، وجود نداشته باشد. به مثال زیر توجه کنید :

مثال

clear all
close all
clc
img=imread(‘image.jpg’);
img=rgb2gray(img);
imshow(img);

figure
histeq(img);

 

نتیجه

تصویر اصلی :

low contrast image

تصویر پس از افزایش کنتراست :

high contrast image

منبع


افزایش کنتراست با Contrast stretching

نرمالایز یا تو فیلد پردازش تصویر Contrast stretching هستش یک تکنیک ساده ارتقاء تصویر هستش که سعی می کنه کنتراست تصویر را افزایش بده این طور تصور کنید که از داده های تصویر تون هیستوگرام گرفتید به صورت شکل زیر شده :

همانطوری که می بینید پراکندگی پیکسل ها در بازه مشخصی هستش و شما در تصویر نه سیاه و نه سفید مطلق دارید با نرمالیز کردن می تونید طوری توزیع را مقدار پیکسل ها را تغییر بدید که کل بازه ۰ تا ۲۵۵ را پوشش بده که هیستوگرام و تصویر بعد از نرمالیزمیشه به صورت زیر:

یک نکته ای را که باید متذکر بشم تفاوت Normalize با histogram equalization هستش عملیات نرمالیز به صورت خطی داده ها را تغییر مقیاس میده ولی عملیات histogram equalization به صورت غیر خطی هستش.

فرمول برای نرمالیز کردن

تصویر فعلی که قرار نرمالیز بشه دارای یک Max و Min هستش و شما قصد دارید تصویر را به بازه جدید تغییر مقیاس دهید یعنی یک بازه با حد پایین NewMin و حد بالای NewMax که ما توی تصویر معمولاً از بازه ۰ و ۲۵۵ استفاده می کنیم. حال باید dynamic range تصویر اصلی و تصویر نهایی را به صورت زیر محاسبه کنید.

dr_src = Max – Min

dr_dst = NewMax – NewMin

پس از آن مقدار scale  را محاسبه می کنیم.

scale = dr_dst/dr_src

I_n = (I – Min) * scale + NewMin

یکی دیگه از کاربردهای آماری دیگه ای که داره گاهی اوقات شما آرایه ای از مقادیر دارید و بازه اعداد ممکنه متفاوت باشند در این شرایط شما می تونید از نرمالیز استفاده کرده و داده را به بازه دلخواه تغییر مقیاس بدید مثال خیلی کاربردیش زمانیکه شما قصد دارید یک شبکه عصبی MLP را آموزش بدید و در شرایطی که active function شما از نوع سیگموید باشه برای همگرایی سریع شبکه باید داده های ورودی شبکه در بازه منفی یک و یک باشه که شما به راحتی می تونید با نرمالیز کردن داده های ورودی به شکل مطلوب تغییرشون بدید.

منبع


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

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

مرحله۱ – PMF ( تابع جرم احتمال ) رو حساب می کنیم .

وقتی هیستوگرام  را محاسبه می کنیم میزان فراوانی یا فرکانس هر سطح خاکستری نمایش داده میشود مانند شکل زیر:

prob1

PMF در ابتدا مجموع فراوانی ها را محاسبه می کند و سپس مقدار هر فراوانی را بر کل فراوانی ها تقسیم می کنیم.

افزایش کنتراست

pmf تابعی است که احتمال وقوع متغیر تصادفی  x=k را نشان میدهد.( دقت داشته باشید که در pmf مقادیر k گسسته هستند) و به این دلیل که این تابع احتمال را نشان می دهدبنانبراین می بایست  دو شرط زیر هم برای این تابع برقرار باشند :

۱_ (p(x باید بزرگتر مساوی ۰ باشد .

۲_ به ازای همه k ها مجموع تمام (p(x=k  ها باید ۱ شود .

برای هیستوگرام عکس هم میشه تابعی با شرایط بالا پیدا کرد :

اگر x را به صورت یک متغیر تصادفی داخل فضای نمونه شامل همه رنگ ها در نظر بگیریم و k  هم مجموعه اعداد ۰ تا ۲۵۵ باشد، pmf را می توان با تقسیم تعداد پیکسل ها با رنگ مورد نظر بر تعداد کل پیکسل ها محاسبه کرد :

p(x=k)=number of pixels with color k / total number of pixels

کد ++C این کار به صورت زیر است :

 

#include "stdafx.h"
#include   < vector >
#include   < string >
#include   < iostream >
#include   < algorithm >
#include   < numeric >
using namespace std;
 
void computePMF(const vector  < int >   &src,vector  < float >   &dst){
    float sum = (float)std::accumulate(src.begin(), src.end(), 0);
 
    dst.resize(src.size());
    for (size_t i=0; i    <    src.size();i++)
        dst[i] = src[i] / sum;
 
}
int _tmain(int argc, _TCHAR* argv[])
{
     
    vector   < int >    hist(10);
    for (auto &item : hist)
        item = rand()%5;
 
    vector   < float >    pmf;
    computePMF(hist,pmf);
 
    for (auto item :pmf)
        cout     <   <     item    <   <     endl;
 
     
     
    return 0;
}

 

pdf

 

مرحله ۲ – با استفاده از PMF  مقادیر CDF ( تابع توزیع تجمعی‌) را حساب می کنیم .

توزیع تجمعی یعنی وقتی PMF را محاسبه کردید بعد از آن مقدار هر اندیس در CDF برابر است با مقدار مجموع همه PMF های کوچکتر و مساوی با آن اندیس می باشد.

اگر PMF به صورت زیر باشد:

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

CDF به صورت زیر خواهد شد.

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

کد ++C محاسبه CDF به صورت زیر می باشد:

 

#include "stdafx.h"
#include   < vector >
#include   < string >
#include   < iostream >
#include   < algorithm >
#include   < numeric >
using namespace std;
 
void computePMF(const vector   < int >   &src,vector   < float >   &dst){
    float sum = (float)std::accumulate(src.begin(), src.end(), 0);
 
    dst.resize(src.size());
    for (size_t i=0; i    <    src.size();i++)
        dst[i] = src[i] / sum;
 
}
void computeCDF(const vector    < float >    pmf,vector<float> &cdf){
    cdf.resize(pmf.size());
    float sum=0;
    for (size_t i=0; i    <   pmf.size();i++){
        cdf[i] = sum + pmf[i];
        sum += pmf[i];
    }
 
}
int _tmain(int argc, _TCHAR* argv[])
{
     
    vector   < int >   hist(10);
    for (auto &item : hist)
        item = rand()%5;
 
    vector   < float >   pmf;
    computePMF(hist,pmf);
 
    vector  < float >   cdf;
    computeCDF(pmf,cdf);
    for (auto item :cdf)
        cout    <   <    item    <   <   endl;
 
     
     
    return 0;
}

 

cdf

 

مرحله ۳ – نهایتا مقادیر CDF بدست آمده رو normalize می کنیم

 

cdf

 

که مقادیر ScaledCDF رنگ خروجی ما هستن

 

 

برای equalize کردن Histogram عکس رنگی بوسیله opencv

اول عکس رو به فضای رنگی YCrCb میبریم

بعد بر روی کانال مربوط به شدت نور بوسیله تابع equalizeHist عملیات مربوطه رو انجام میدیم

کد :

 

#include   < opencv2/highgui/highgui.hpp >
#include   < opencv2/imgproc/imgproc.hpp >
#include   < iostream >
 
using namespace cv;
 
int main( )
{
    const char* original_window="Source";
    const char* equalized_window="Equalized image";
 
    Mat image = imread("F:\\image1.jpg");
    Mat equalized_image;
    std::vector  < Mat >    channels;
 
    cvtColor(image, equalized_image, CV_BGR2YCrCb); 
 
    split(equalized_image,channels);
    equalizeHist(channels[0], channels[0]);
 
    merge(channels,equalized_image); 
    cvtColor(equalized_image, equalized_image, CV_YCrCb2BGR);
 
    namedWindow(original_window,WINDOW_NORMAL);
    namedWindow(equalized_window,WINDOW_NORMAL);
 
    imshow(original_window,image);
    imshow(equalized_window,equalized_image);
 
    waitKey(0);
}

 

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

 

این کد هم به زبان ++C است که به راحتی قابل تبدیل به #C می باشد:

 

#include   < iostream >
#include   < opencv2/highgui/highgui.hpp >
#include   < opencv2/imgproc/imgproc.hpp >
 
using std::cout;
using std::cin;
using std::endl;
 
using namespace cv;
 
void imhist(Mat image, int histogram[])
{
 
    // initialize all intensity values to 0
    for(int i = 0; i    <    256; i++)
    {
        histogram[i] = 0;
    }
 
    // calculate the no of pixels for each intensity values
    for(int y = 0; y    <    image.rows; y++)
        for(int x = 0; x    <    image.cols; x++)
            histogram[(int)image.at   < uchar >   (y,x)]++;
 
}
 
void cumhist(int histogram[], int cumhistogram[])
{
    cumhistogram[0] = histogram[0];
 
    for(int i = 1; i   <   256; i++)
    {
        cumhistogram[i] = histogram[i] + cumhistogram[i-1];
    }
}
 
void histDisplay(int histogram[], const char* name)
{
    int hist[256];
    for(int i = 0; i    <    256; i++)
    {
        hist[i]=histogram[i];
    }
    // draw the histograms
    int hist_w = 512; int hist_h = 400;
    int bin_w = cvRound((double) hist_w/256);
 
    Mat histImage(hist_h, hist_w, CV_8UC1, Scalar(255, 255, 255));
 
    // find the maximum intensity element from histogram
    int max = hist[0];
    for(int i = 1; i   <    256; i++){
        if(max    <    hist[i]){
            max = hist[i];
        }
    }
 
    // normalize the histogram between 0 and histImage.rows
 
    for(int i = 0; i    <    256; i++){
        hist[i] = ((double)hist[i]/max)*histImage.rows;
    }
 
 
    // draw the intensity line for histogram
    for(int i = 0; i   <   256; i++)
    {
        line(histImage, Point(bin_w*(i), hist_h),
                              Point(bin_w*(i), hist_h - hist[i]),
             Scalar(0,0,0), 1, 8, 0);
    }
 
    // display histogram
    namedWindow(name, CV_WINDOW_AUTOSIZE);
    imshow(name, histImage);
}
 
 
 
int main()
{
    // Load the image
    Mat image = imread("scene.jpg", CV_LOAD_IMAGE_GRAYSCALE);
 
    // Generate the histogram
    int histogram[256];
    imhist(image, histogram);
 
    // Caluculate the size of image
    int size = image.rows * image.cols;
    float alpha = 255.0/size;
 
    // Calculate the probability of each intensity
    float PrRk[256];
    for(int i = 0; i    <    256; i++)
    {
        PrRk[i] = (double)histogram[i] / size;
    }
 
    // Generate cumulative frequency histogram
    int cumhistogram[256];
    cumhist(histogram,cumhistogram );
 
    // Scale the histogram
    int Sk[256];
    for(int i = 0; i   <   256; i++)
    {
        Sk[i] = cvRound((double)cumhistogram[i] * alpha);
    }
 
 
    // Generate the equlized histogram
    float PsSk[256];
    for(int i = 0; i   <   256; i++)
    {
        PsSk[i] = 0;
    }
 
    for(int i = 0; i   <   256; i++)
    {
        PsSk[Sk[i]] += PrRk[i];
    }
 
    int final[256];
    for(int i = 0; i    <    256; i++)
        final[i] = cvRound(PsSk[i]*255);
 
 
    // Generate the equlized image
    Mat new_image = image.clone();
 
    for(int y = 0; y    <    image.rows; y++)
        for(int x = 0; x    <    image.cols; x++)
            new_image.at   < uchar >   (y,x) = saturate_cast   < uchar >   (Sk[image.at   < uchar >   (y,x)]);
 
   // Display the original Image
    namedWindow("Original Image");
    imshow("Original Image", image);
 
    // Display the original Histogram
    histDisplay(histogram, "Original Histogram");
 
    // Display equilized image
    namedWindow("Equilized Image");
    imshow("Equilized Image",new_image);
 
    // Display the equilzed histogram
    histDisplay(final, "Equilized Histogram");
 
    waitKey();
    return 0;
}

 

منبع

 

 

 

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *