當(dāng)前位置:
首頁 >
视频清晰度、色偏以及亮度异常检测
發(fā)布時間:2025/3/21
54
豆豆
生活随笔
收集整理的這篇文章主要介紹了
视频清晰度、色偏以及亮度异常检测
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
原文鏈接:http://blog.csdn.net/kklots/article/details/12720359
昨天老板臨時交代一個活,要求通過算法檢測監(jiān)控設(shè)備是否存在失焦、偏色、亮度異常等問題。問題本身不難,在網(wǎng)上查看了一些資料,自己也做了一些思考,方法如下:
? ? ? ? 1.失焦檢測。
? ? ? ? 失焦的主要表現(xiàn)就是畫面模糊,衡量畫面模糊的主要方法就是梯度的統(tǒng)計(jì)特征,通常梯度值越高,畫面的邊緣信息越豐富,圖像越清晰。需要注意的是梯度信息與每一個視頻本身的特點(diǎn)有關(guān)系,如果畫面中本身的紋理就很少,即使不失焦,梯度統(tǒng)計(jì)信息也會很少,對監(jiān)控設(shè)備失焦檢測需要人工參與的標(biāo)定過程,由人告訴計(jì)算機(jī)某個設(shè)備正常情況下的紋理信息是怎樣的。
/******************************************************************************** *函數(shù)描述: DefRto 計(jì)算并返回一幅圖像的清晰度 *函數(shù)參數(shù): frame 彩色幀圖 *函數(shù)返回值:double 清晰度表示值,針對該視頻,當(dāng)清晰度小于10為模糊,大于14為清楚 *********************************************************************************/ double DefRto(Mat frame) { Mat gray; cvtColor(frame,gray,CV_BGR2GRAY); IplImage *img = &(IplImage(gray)); double temp = 0; double DR = 0; int i,j;//循環(huán)變量 int height=img->height; int width=img->width; int step=img->widthStep/sizeof(uchar); uchar *data=(uchar*)img->imageData; double num = width*height; for(i=0;i<height;i++) { for(j=0;j<width;j++) { temp += sqrt((pow((double)(data[(i+1)*step+j]-data[i*step+j]),2) + pow((double)(data[i*step+j+1]-data[i*step+j]),2))); temp += abs(data[(i+1)*step+j]-data[i*step+j])+abs(data[i*step+j+1]-data[i*step+j]); } } DR = temp/num; return DR; }
? ? ? ? 2.色偏檢測。
? ? ? ? 網(wǎng)上常用的一種方法是將RGB圖像轉(zhuǎn)變到CIE L*a*b*空間,其中L*表示圖像亮度,a*表示圖像紅/綠分量,b*表示圖像黃/藍(lán)分量。通常存在色偏的圖像,在a*和b*分量上的均值會偏離原點(diǎn)很遠(yuǎn),方差也會偏小;通過計(jì)算圖像在a*和b*分量上的均值和方差,就可評估圖像是否存在色偏。計(jì)算CIE L*a*b*空間是一個比較繁瑣的過程,好在OpenCV提供了現(xiàn)成的函數(shù),因此整個過程也不復(fù)雜。
/******************************************************************************************** *函數(shù)描述: calcCast 計(jì)算并返回一幅圖像的色偏度以及,色偏方向 *函數(shù)參數(shù): InputImg 需要計(jì)算的圖片,BGR存放格式,彩色(3通道),灰度圖無效 * cast 計(jì)算出的偏差值,小于1表示比較正常,大于1表示存在色偏 * da 紅/綠色偏估計(jì)值,da大于0,表示偏紅;da小于0表示偏綠 * db 黃/藍(lán)色偏估計(jì)值,db大于0,表示偏黃;db小于0表示偏藍(lán) *函數(shù)返回值: 返回值通過cast、da、db三個應(yīng)用返回,無顯式返回值 *********************************************************************************************/ void colorException(Mat InputImg,float& cast,float& da,float& db) { Mat LABimg; cvtColor(InputImg,LABimg,CV_BGR2Lab);//參考http://blog.csdn.net/laviewpbt/article/details/9335767 //由于OpenCV定義的格式是uint8,這里輸出的LABimg從標(biāo)準(zhǔn)的0~100,-127~127,-127~127,被映射到了0~255,0~255,0~255空間 float a=0,b=0; int HistA[256],HistB[256]; for(int i=0;i<256;i++) { HistA[i]=0; HistB[i]=0; } for(int i=0;i<LABimg.rows;i++) { for(int j=0;j<LABimg.cols;j++) { a+=float(LABimg.at<cv::Vec3b>(i,j)[1]-128);//在計(jì)算過程中,要考慮將CIE L*a*b*空間還原 后同 b+=float(LABimg.at<cv::Vec3b>(i,j)[2]-128); int x=LABimg.at<cv::Vec3b>(i,j)[1]; int y=LABimg.at<cv::Vec3b>(i,j)[2]; HistA[x]++; HistB[y]++; } } da=a/float(LABimg.rows*LABimg.cols); db=b/float(LABimg.rows*LABimg.cols); float D =sqrt(da*da+db*db); float Ma=0,Mb=0; for(int i=0;i<256;i++) { Ma+=abs(i-128-da)*HistA[i];//計(jì)算范圍-128~127 Mb+=abs(i-128-db)*HistB[i]; } Ma/=float((LABimg.rows*LABimg.cols)); Mb/=float((LABimg.rows*LABimg.cols)); float M=sqrt(Ma*Ma+Mb*Mb); float K=D/M; cast = K; return; }
? ? ? ? 3.亮度檢測。
? ? ? ? 亮度檢測與色偏檢測相似,計(jì)算圖片在灰度圖上的均值和方差,當(dāng)存在亮度異常時,均值會偏離均值點(diǎn)(可以假設(shè)為128),方差也會偏小;通過計(jì)算灰度圖的均值和方差,就可評估圖像是否存在過曝光或曝光不足。函數(shù)如下:
/********************************************************************************************************************************************************* *函數(shù)描述: brightnessException 計(jì)算并返回一幅圖像的色偏度以及,色偏方向 *函數(shù)參數(shù): InputImg 需要計(jì)算的圖片,BGR存放格式,彩色(3通道),灰度圖無效 * cast 計(jì)算出的偏差值,小于1表示比較正常,大于1表示存在亮度異常;當(dāng)cast異常時,da大于0表示過亮,da小于0表示過暗 *函數(shù)返回值: 返回值通過cast、da兩個引用返回,無顯式返回值 **********************************************************************************************************************************************************/ void brightnessException (Mat InputImg,float& cast,float& da) { Mat GRAYimg; cvtColor(InputImg,GRAYimg,CV_BGR2GRAY); float a=0; int Hist[256]; for(int i=0;i<256;i++) Hist[i]=0; for(int i=0;i<GRAYimg.rows;i++) { for(int j=0;j<GRAYimg.cols;j++) { a+=float(GRAYimg.at<uchar>(i,j)-128);//在計(jì)算過程中,考慮128為亮度均值點(diǎn) int x=GRAYimg.at<uchar>(i,j); Hist[x]++; } } da=a/float(GRAYimg.rows*InputImg.cols); float D =abs(da); float Ma=0; for(int i=0;i<256;i++) { Ma+=abs(i-128-da)*Hist[i]; } Ma/=float((GRAYimg.rows*GRAYimg.cols)); float M=abs(Ma); float K=D/M; cast = K; return; }
昨天老板臨時交代一個活,要求通過算法檢測監(jiān)控設(shè)備是否存在失焦、偏色、亮度異常等問題。問題本身不難,在網(wǎng)上查看了一些資料,自己也做了一些思考,方法如下:
? ? ? ? 1.失焦檢測。
? ? ? ? 失焦的主要表現(xiàn)就是畫面模糊,衡量畫面模糊的主要方法就是梯度的統(tǒng)計(jì)特征,通常梯度值越高,畫面的邊緣信息越豐富,圖像越清晰。需要注意的是梯度信息與每一個視頻本身的特點(diǎn)有關(guān)系,如果畫面中本身的紋理就很少,即使不失焦,梯度統(tǒng)計(jì)信息也會很少,對監(jiān)控設(shè)備失焦檢測需要人工參與的標(biāo)定過程,由人告訴計(jì)算機(jī)某個設(shè)備正常情況下的紋理信息是怎樣的。
/******************************************************************************** *函數(shù)描述: DefRto 計(jì)算并返回一幅圖像的清晰度 *函數(shù)參數(shù): frame 彩色幀圖 *函數(shù)返回值:double 清晰度表示值,針對該視頻,當(dāng)清晰度小于10為模糊,大于14為清楚 *********************************************************************************/ double DefRto(Mat frame) { Mat gray; cvtColor(frame,gray,CV_BGR2GRAY); IplImage *img = &(IplImage(gray)); double temp = 0; double DR = 0; int i,j;//循環(huán)變量 int height=img->height; int width=img->width; int step=img->widthStep/sizeof(uchar); uchar *data=(uchar*)img->imageData; double num = width*height; for(i=0;i<height;i++) { for(j=0;j<width;j++) { temp += sqrt((pow((double)(data[(i+1)*step+j]-data[i*step+j]),2) + pow((double)(data[i*step+j+1]-data[i*step+j]),2))); temp += abs(data[(i+1)*step+j]-data[i*step+j])+abs(data[i*step+j+1]-data[i*step+j]); } } DR = temp/num; return DR; }
? ? ? ? 2.色偏檢測。
? ? ? ? 網(wǎng)上常用的一種方法是將RGB圖像轉(zhuǎn)變到CIE L*a*b*空間,其中L*表示圖像亮度,a*表示圖像紅/綠分量,b*表示圖像黃/藍(lán)分量。通常存在色偏的圖像,在a*和b*分量上的均值會偏離原點(diǎn)很遠(yuǎn),方差也會偏小;通過計(jì)算圖像在a*和b*分量上的均值和方差,就可評估圖像是否存在色偏。計(jì)算CIE L*a*b*空間是一個比較繁瑣的過程,好在OpenCV提供了現(xiàn)成的函數(shù),因此整個過程也不復(fù)雜。
/******************************************************************************************** *函數(shù)描述: calcCast 計(jì)算并返回一幅圖像的色偏度以及,色偏方向 *函數(shù)參數(shù): InputImg 需要計(jì)算的圖片,BGR存放格式,彩色(3通道),灰度圖無效 * cast 計(jì)算出的偏差值,小于1表示比較正常,大于1表示存在色偏 * da 紅/綠色偏估計(jì)值,da大于0,表示偏紅;da小于0表示偏綠 * db 黃/藍(lán)色偏估計(jì)值,db大于0,表示偏黃;db小于0表示偏藍(lán) *函數(shù)返回值: 返回值通過cast、da、db三個應(yīng)用返回,無顯式返回值 *********************************************************************************************/ void colorException(Mat InputImg,float& cast,float& da,float& db) { Mat LABimg; cvtColor(InputImg,LABimg,CV_BGR2Lab);//參考http://blog.csdn.net/laviewpbt/article/details/9335767 //由于OpenCV定義的格式是uint8,這里輸出的LABimg從標(biāo)準(zhǔn)的0~100,-127~127,-127~127,被映射到了0~255,0~255,0~255空間 float a=0,b=0; int HistA[256],HistB[256]; for(int i=0;i<256;i++) { HistA[i]=0; HistB[i]=0; } for(int i=0;i<LABimg.rows;i++) { for(int j=0;j<LABimg.cols;j++) { a+=float(LABimg.at<cv::Vec3b>(i,j)[1]-128);//在計(jì)算過程中,要考慮將CIE L*a*b*空間還原 后同 b+=float(LABimg.at<cv::Vec3b>(i,j)[2]-128); int x=LABimg.at<cv::Vec3b>(i,j)[1]; int y=LABimg.at<cv::Vec3b>(i,j)[2]; HistA[x]++; HistB[y]++; } } da=a/float(LABimg.rows*LABimg.cols); db=b/float(LABimg.rows*LABimg.cols); float D =sqrt(da*da+db*db); float Ma=0,Mb=0; for(int i=0;i<256;i++) { Ma+=abs(i-128-da)*HistA[i];//計(jì)算范圍-128~127 Mb+=abs(i-128-db)*HistB[i]; } Ma/=float((LABimg.rows*LABimg.cols)); Mb/=float((LABimg.rows*LABimg.cols)); float M=sqrt(Ma*Ma+Mb*Mb); float K=D/M; cast = K; return; }
? ? ? ? 3.亮度檢測。
? ? ? ? 亮度檢測與色偏檢測相似,計(jì)算圖片在灰度圖上的均值和方差,當(dāng)存在亮度異常時,均值會偏離均值點(diǎn)(可以假設(shè)為128),方差也會偏小;通過計(jì)算灰度圖的均值和方差,就可評估圖像是否存在過曝光或曝光不足。函數(shù)如下:
/********************************************************************************************************************************************************* *函數(shù)描述: brightnessException 計(jì)算并返回一幅圖像的色偏度以及,色偏方向 *函數(shù)參數(shù): InputImg 需要計(jì)算的圖片,BGR存放格式,彩色(3通道),灰度圖無效 * cast 計(jì)算出的偏差值,小于1表示比較正常,大于1表示存在亮度異常;當(dāng)cast異常時,da大于0表示過亮,da小于0表示過暗 *函數(shù)返回值: 返回值通過cast、da兩個引用返回,無顯式返回值 **********************************************************************************************************************************************************/ void brightnessException (Mat InputImg,float& cast,float& da) { Mat GRAYimg; cvtColor(InputImg,GRAYimg,CV_BGR2GRAY); float a=0; int Hist[256]; for(int i=0;i<256;i++) Hist[i]=0; for(int i=0;i<GRAYimg.rows;i++) { for(int j=0;j<GRAYimg.cols;j++) { a+=float(GRAYimg.at<uchar>(i,j)-128);//在計(jì)算過程中,考慮128為亮度均值點(diǎn) int x=GRAYimg.at<uchar>(i,j); Hist[x]++; } } da=a/float(GRAYimg.rows*InputImg.cols); float D =abs(da); float Ma=0; for(int i=0;i<256;i++) { Ma+=abs(i-128-da)*Hist[i]; } Ma/=float((GRAYimg.rows*GRAYimg.cols)); float M=abs(Ma); float K=D/M; cast = K; return; }
? ? ? ? 最后展示一下結(jié)果
可以發(fā)現(xiàn):當(dāng)亮度變低時,失焦檢測顯示結(jié)果為:模糊。這是由于失焦檢測依賴于梯度統(tǒng)計(jì),亮度變低時,會導(dǎo)致梯度值整體下降,從而導(dǎo)致檢測不正確。一種更好的方法是利用亮度檢測的結(jié)果,合理設(shè)定失焦檢測的報(bào)警閾值,避免這種情況。
總結(jié)
以上是生活随笔為你收集整理的视频清晰度、色偏以及亮度异常检测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu13.10下编译安装open
- 下一篇: win32下安装mingw32和cmak