圖像指定區(qū)域的亮度增強(qiáng)與直方圖繪制

圖像亮度增強(qiáng)

圖像的亮度變化脑豹,簡(jiǎn)單來說就是對(duì)圖像像素的線性變化研叫,公式如下所示:
g_{i,j}(x) = \alpha f_{i,j}(x)+ \beta
其中,f_{i,j}(x)表示第i行处铛,第j列的像素值赖晶,g_{i,j}(x)表示亮度變換后的像素值。綜上,圖像亮度變化的代碼如下:


static const double alpha = 1.5;
static const double beta = -90;
void highLigh(Mat& img,int x0,int y0,int x1,int y1) //指定區(qū)域進(jìn)行亮度調(diào)整
{
    for (int i=x0;i<x1;i++)
    {
        for (int j = y0; j < y1; j++)
        {
            for (int c = 0; c < 3; c++)
            {
                img.at<Vec3b>(j, i)[c] = saturate_cast<uchar>(img.at<Vec3b>(j, i)[c] * alpha + beta);
            }
        }
    }

}

指定區(qū)域的亮度增強(qiáng)和直方圖繪制

對(duì)于一副圖像有如下要求:

  1. 加載并顯示圖像,通過鼠標(biāo)左鍵拖拽選定指定區(qū)域扯旷,當(dāng)釋放左鍵時(shí),對(duì)選定的區(qū)域?qū)崿F(xiàn)亮度增強(qiáng)索抓。
  2. 對(duì)選定的區(qū)域?qū)崿F(xiàn)直方圖繪制钧忽,橫軸每個(gè)單位區(qū)間指定為32個(gè)像素值(即0-31,32-63…,224-255)逼肯,而縱軸顯示為區(qū)間像素出現(xiàn)的次數(shù)耸黑。對(duì)于一副RGB三通道圖像,用紅色表示R通道的直方圖分布篮幢,綠色表示G通道的像素分布大刊,藍(lán)色表示B通道。

針對(duì)以上問題三椿,利用C++和opencv實(shí)現(xiàn)的代碼如下所示:


#include<iostream>

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include<opencv2/opencv.hpp>
using namespace cv;

/*
create a program that reads in and displays an image.
a. Allow the user to select a rectangular region in the image by drawing a rectangle with the mouse button held down
   and highlight the region when the mouse button is released.Be careful to save an image copy in memory so that your
   drawing into the image dose not destory the original values there. The next mouse click should start the process all
   over again from the original image
b. In a separate window,use the drawing functions to draw a graph in blue,green,and red that represents how many pixels
  of each value were found in the selected box.This is the color histofram of that color region.The x-axis should be eight
  bins that represent pixel values falling within the ranges 0-31,32-63,…,223-255.The y-axis should be counts of the number
  of pixels that were found ub that bin range.Do this for each color channel.BGR.

*/


Point2i initP(0, 0); // 記錄初始點(diǎn)坐標(biāo)
static const double alpha = 1.5;
static const double beta = -90;
void highLigh(Mat& img,int x0,int y0,int x1,int y1) //指定區(qū)域進(jìn)行亮度調(diào)整
{
    for (int i=x0;i<x1;i++)
    {
        for (int j = y0; j < y1; j++)
        {
            for (int c = 0; c < 3; c++)
            {
                img.at<Vec3b>(j, i)[c] = saturate_cast<uchar>(img.at<Vec3b>(j, i)[c] * alpha + beta);
            }
        }
    }

}


void histGraph(Mat& histMat,Mat& histImg, const int& width,const Scalar& rgb)
{
    double maxVal = 0;
    minMaxLoc(histMat, 0, &maxVal, 0, 0);
    for (int h = 0; h < width; h++)
    {
        int value = cvRound(histImg.rows * 0.9 * histMat.at<float>(h) / maxVal);
        rectangle(histImg, Point(h * (histImg.cols/width), (histImg.rows - 1)), Point((h + 1) * (histImg.cols/width), histImg.rows - 1 - value), rgb, -1);
    }
}
void HandlerMouseEvent(int event,int x,int y,int flags,void *p)
{
    Mat srcImg = *(static_cast<Mat*>(p));
    Mat cloneImg = srcImg.clone();
    //Mat histdigram;
    const int channels[] = { 0,1,2 }; //繪制直方圖:3個(gè)通道
    int bins_ranges[] = {32};
    MatND m_hist;  //直方圖輸出
    float hranges[] = { 0,256 };
    const float* ranges[] = {hranges}; //直方圖縱軸
    
    
    switch (event)
    {
    case EVENT_LBUTTONDOWN:
    {

        initP.x = x;
        initP.y = y;
        break;

    }
    case (EVENT_MOUSEMOVE &&  (flags&EVENT_FLAG_LBUTTON)):
    {
        rectangle(cloneImg, Rect2i(initP, Point2i(x, y)), Scalar(233, 233, 84), 1, 8, 0);
        //highLigh(cloneImg, initP.x, initP.y, x, y);
        imshow("SelectRectImage", cloneImg);
        break;

    }
    
    case EVENT_LBUTTONUP:
    {
        
        highLigh(cloneImg, initP.x, initP.y, x, y);
        imshow("selectRectImage", cloneImg);
        //畫直方圖
        Mat histdigram = Mat(cloneImg, Rect(initP, Point2d(x, y)));
        std::vector<Mat> bgr_channels;
        split(histdigram, bgr_channels);  //通道分離
        Mat m_hist1, m_hist2, m_hist3;
        calcHist(&bgr_channels[0], 1, 0, Mat(),  m_hist1, 1, bins_ranges, ranges, true, false);
        calcHist(&bgr_channels[1], 1, 0, Mat(), m_hist2, 1, bins_ranges, ranges, true, false);
        calcHist(&bgr_channels[2], 1, 0, Mat(), m_hist3, 1, bins_ranges, ranges, true, false);
        
        
        Mat histImg = Mat::zeros(512, 512, CV_8UC3);
        histGraph(m_hist1, histImg, bins_ranges[0], Scalar(255, 0, 0));
        histGraph(m_hist2, histImg, bins_ranges[0], Scalar(0, 255, 0));
        histGraph(m_hist3, histImg, bins_ranges[0], Scalar(0, 0, 255));

        
        imshow("HistTest", histImg);
        break;
    }
    
    
    }

}

int main()
{
    Mat img = imread("ex3.jpg");
    namedWindow("SelectRectImage",0);
    namedWindow("HistTest"); //顯示直方圖視圖
    setMouseCallback("SelectRectImage", HandlerMouseEvent,&img);
    HandlerMouseEvent(0, 0, 0, 1,&img);
    imshow("SelectRectImage", img);
    waitKey(0);

    return 0;
}

根據(jù)以上代碼缺菌,實(shí)現(xiàn)效果如下:

對(duì)選定ROI區(qū)域進(jìn)行亮度增強(qiáng),并繪制ROI區(qū)域的直方圖

注意:直方圖繪制中赋续,利用了opencv提供的calchist()函數(shù)男翰,對(duì)于此函數(shù)的參數(shù)參數(shù)另患,有如下解釋:

void cv::calchist(const Mat* images,     //輸入圖像(源圖像)纽乱,具有相同的深度和尺寸
                          int nimages,        //輸出圖像的數(shù)量
                          const int* channels,   //通道數(shù)量,對(duì)于多幅圖像而言昆箕,第一個(gè)圖像的通道數(shù)為0-images[0].channels(),第二個(gè)數(shù)組通道為images[0].channels()-images[0].channels()+images[1].channels()-1,以此類推
                          inputArray mask,        //可選參數(shù)鸦列,一般默認(rèn)為Mat(),如果不為空,設(shè)定為與images[i]相同的尺寸
                          outputArray hist,       //直方圖輸出,一個(gè)密集或稀疏矩陣
                          int dims,                   // 直方圖的維數(shù)鹏倘,必須是正值且大于 CV_MAX_DIMS
                          const int* histSIze,   //直方圖每一個(gè)維度的大小
                          const float** ranges,  // 每個(gè)維度中直方圖bin邊界的dims數(shù)組薯嗤。 當(dāng)直方圖是均勻的時(shí)(uniform = true),則對(duì)于每個(gè)維度i纤泵,足以指定第0個(gè)直方圖bin的下(包含)邊界L0和上界(專有)邊界UhistSize [i] -1 最后一個(gè)直方圖bin histSize [i] -1骆姐。 也就是說,在均勻的直方圖的情況下捏题,range [i]中的每個(gè)都是2個(gè)元素的數(shù)組玻褪。 當(dāng)直方圖不一致時(shí)(均等= false),則每個(gè)range [i]都包含histSize [i] +1個(gè)元素:L0公荧,U0 = L1带射,U1 = L2,...循狰,UhistSize [i] -2 = LhistSize [i] -1窟社,UhistSize [i] -1券勺。 不在L0和UhistSize [i] -1之間的數(shù)組元素不計(jì)入直方圖。
                          bool uniform = true,  // 是否均勻分布
                          bool accumulate=false  //累加標(biāo)記灿里,當(dāng)設(shè)置為1時(shí)关炼,當(dāng)分配直方圖時(shí),不會(huì)清楚初始狀態(tài)匣吊,此功能可以從幾組數(shù)組中計(jì)算單個(gè)直方圖或者及時(shí)更新直方圖盗扒。


)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市缀去,隨后出現(xiàn)的幾起案子侣灶,更是在濱河造成了極大的恐慌,老刑警劉巖缕碎,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件褥影,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡咏雌,警方通過查閱死者的電腦和手機(jī)凡怎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赊抖,“玉大人统倒,你說我怎么就攤上這事》昭” “怎么了房匆?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)报亩。 經(jīng)常有香客問我浴鸿,道長(zhǎng),這世上最難降的妖魔是什么弦追? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任岳链,我火速辦了婚禮,結(jié)果婚禮上劲件,老公的妹妹穿的比我還像新娘掸哑。我一直安慰自己,他們只是感情好零远,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布苗分。 她就那樣靜靜地躺著,像睡著了一般遍烦。 火紅的嫁衣襯著肌膚如雪俭嘁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天服猪,我揣著相機(jī)與錄音供填,去河邊找鬼拐云。 笑死,一個(gè)胖子當(dāng)著我的面吹牛近她,可吹牛的內(nèi)容都是我干的叉瘩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼粘捎,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼薇缅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起攒磨,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤泳桦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后娩缰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灸撰,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年拼坎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浮毯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泰鸡,死狀恐怖债蓝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盛龄,我是刑警寧澤饰迹,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站讯嫂,受9級(jí)特大地震影響蹦锋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜欧芽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望葛圃。 院中可真熱鬧千扔,春花似錦、人聲如沸库正。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)褥符。三九已至龙誊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間喷楣,已是汗流浹背趟大。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工鹤树, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逊朽。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓罕伯,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親叽讳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子追他,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359