视频清晰度、色偏以及亮度异常检测
生活随笔
收集整理的這篇文章主要介紹了
视频清晰度、色偏以及亮度异常检测
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文鏈接:http://blog.csdn.net/kklots/article/details/12720359
昨天老板臨時交代一個活,要求通過算法檢測監控設備是否存在失焦、偏色、亮度異常等問題。問題本身不難,在網上查看了一些資料,自己也做了一些思考,方法如下:
? ? ? ? 1.失焦檢測。
? ? ? ? 失焦的主要表現就是畫面模糊,衡量畫面模糊的主要方法就是梯度的統計特征,通常梯度值越高,畫面的邊緣信息越豐富,圖像越清晰。需要注意的是梯度信息與每一個視頻本身的特點有關系,如果畫面中本身的紋理就很少,即使不失焦,梯度統計信息也會很少,對監控設備失焦檢測需要人工參與的標定過程,由人告訴計算機某個設備正常情況下的紋理信息是怎樣的。
/******************************************************************************** *函數描述: DefRto 計算并返回一幅圖像的清晰度 *函數參數: frame 彩色幀圖 *函數返回值:double 清晰度表示值,針對該視頻,當清晰度小于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;//循環變量 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.色偏檢測。
? ? ? ? 網上常用的一種方法是將RGB圖像轉變到CIE L*a*b*空間,其中L*表示圖像亮度,a*表示圖像紅/綠分量,b*表示圖像黃/藍分量。通常存在色偏的圖像,在a*和b*分量上的均值會偏離原點很遠,方差也會偏小;通過計算圖像在a*和b*分量上的均值和方差,就可評估圖像是否存在色偏。計算CIE L*a*b*空間是一個比較繁瑣的過程,好在OpenCV提供了現成的函數,因此整個過程也不復雜。
/******************************************************************************************** *函數描述: calcCast 計算并返回一幅圖像的色偏度以及,色偏方向 *函數參數: InputImg 需要計算的圖片,BGR存放格式,彩色(3通道),灰度圖無效 * cast 計算出的偏差值,小于1表示比較正常,大于1表示存在色偏 * da 紅/綠色偏估計值,da大于0,表示偏紅;da小于0表示偏綠 * db 黃/藍色偏估計值,db大于0,表示偏黃;db小于0表示偏藍 *函數返回值: 返回值通過cast、da、db三個應用返回,無顯式返回值 *********************************************************************************************/ 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從標準的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);//在計算過程中,要考慮將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];//計算范圍-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.亮度檢測。
? ? ? ? 亮度檢測與色偏檢測相似,計算圖片在灰度圖上的均值和方差,當存在亮度異常時,均值會偏離均值點(可以假設為128),方差也會偏小;通過計算灰度圖的均值和方差,就可評估圖像是否存在過曝光或曝光不足。函數如下:
/********************************************************************************************************************************************************* *函數描述: brightnessException 計算并返回一幅圖像的色偏度以及,色偏方向 *函數參數: InputImg 需要計算的圖片,BGR存放格式,彩色(3通道),灰度圖無效 * cast 計算出的偏差值,小于1表示比較正常,大于1表示存在亮度異常;當cast異常時,da大于0表示過亮,da小于0表示過暗 *函數返回值: 返回值通過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);//在計算過程中,考慮128為亮度均值點 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; }
昨天老板臨時交代一個活,要求通過算法檢測監控設備是否存在失焦、偏色、亮度異常等問題。問題本身不難,在網上查看了一些資料,自己也做了一些思考,方法如下:
? ? ? ? 1.失焦檢測。
? ? ? ? 失焦的主要表現就是畫面模糊,衡量畫面模糊的主要方法就是梯度的統計特征,通常梯度值越高,畫面的邊緣信息越豐富,圖像越清晰。需要注意的是梯度信息與每一個視頻本身的特點有關系,如果畫面中本身的紋理就很少,即使不失焦,梯度統計信息也會很少,對監控設備失焦檢測需要人工參與的標定過程,由人告訴計算機某個設備正常情況下的紋理信息是怎樣的。
/******************************************************************************** *函數描述: DefRto 計算并返回一幅圖像的清晰度 *函數參數: frame 彩色幀圖 *函數返回值:double 清晰度表示值,針對該視頻,當清晰度小于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;//循環變量 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.色偏檢測。
? ? ? ? 網上常用的一種方法是將RGB圖像轉變到CIE L*a*b*空間,其中L*表示圖像亮度,a*表示圖像紅/綠分量,b*表示圖像黃/藍分量。通常存在色偏的圖像,在a*和b*分量上的均值會偏離原點很遠,方差也會偏小;通過計算圖像在a*和b*分量上的均值和方差,就可評估圖像是否存在色偏。計算CIE L*a*b*空間是一個比較繁瑣的過程,好在OpenCV提供了現成的函數,因此整個過程也不復雜。
/******************************************************************************************** *函數描述: calcCast 計算并返回一幅圖像的色偏度以及,色偏方向 *函數參數: InputImg 需要計算的圖片,BGR存放格式,彩色(3通道),灰度圖無效 * cast 計算出的偏差值,小于1表示比較正常,大于1表示存在色偏 * da 紅/綠色偏估計值,da大于0,表示偏紅;da小于0表示偏綠 * db 黃/藍色偏估計值,db大于0,表示偏黃;db小于0表示偏藍 *函數返回值: 返回值通過cast、da、db三個應用返回,無顯式返回值 *********************************************************************************************/ 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從標準的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);//在計算過程中,要考慮將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];//計算范圍-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.亮度檢測。
? ? ? ? 亮度檢測與色偏檢測相似,計算圖片在灰度圖上的均值和方差,當存在亮度異常時,均值會偏離均值點(可以假設為128),方差也會偏小;通過計算灰度圖的均值和方差,就可評估圖像是否存在過曝光或曝光不足。函數如下:
/********************************************************************************************************************************************************* *函數描述: brightnessException 計算并返回一幅圖像的色偏度以及,色偏方向 *函數參數: InputImg 需要計算的圖片,BGR存放格式,彩色(3通道),灰度圖無效 * cast 計算出的偏差值,小于1表示比較正常,大于1表示存在亮度異常;當cast異常時,da大于0表示過亮,da小于0表示過暗 *函數返回值: 返回值通過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);//在計算過程中,考慮128為亮度均值點 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; }
? ? ? ? 最后展示一下結果
可以發現:當亮度變低時,失焦檢測顯示結果為:模糊。這是由于失焦檢測依賴于梯度統計,亮度變低時,會導致梯度值整體下降,從而導致檢測不正確。一種更好的方法是利用亮度檢測的結果,合理設定失焦檢測的報警閾值,避免這種情況。
總結
以上是生活随笔為你收集整理的视频清晰度、色偏以及亮度异常检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu13.10下编译安装open
- 下一篇: win32下安装mingw32和cmak