簡單的影象顯著性區域特徵提取方法-----opencv實現LC,AC,FT
阿新 • • 發佈:2019-01-01
上文講了幾種簡單的方法,顯著性檢測就是把一幅影象中最吸引人注意的部分提取出來。
我用opencv重寫了LC,AC,FT三種演算法,程式碼和效果如下:
1.,後面的方法其實大概都是基於這個實現的,程式碼樣子差不多 LC思路就是利用對某個畫素點累加其與全幅畫素的距離(歐式距離),然後歸一化到0-255,由於是rgb資訊,於是用直方圖優化,提前計算好每個顏色與其他的距離和
2.AC演算法也挺有意思,利用了類似影象金字塔演算法,在不同緯度(具體實現是用大小不同的均值濾波器過濾影象)與標準影象做差並累加,然後歸一化,實現如下:
SalientRegionDetectionBasedonAC(test,test.rows/8,test.rows/2,3);
3.FT演算法 lab空間的均值減去當前畫素值
1.,後面的方法其實大概都是基於這個實現的,程式碼樣子差不多 LC思路就是利用對某個畫素點累加其與全幅畫素的距離(歐式距離),然後歸一化到0-255,由於是rgb資訊,於是用直方圖優化,提前計算好每個顏色與其他的距離和
效果圖void SalientRegionDetectionBasedonLC(Mat &src){ int HistGram[256]={0}; int row=src.rows,col=src.cols; int gray[row][col]; //int Sal_org[row][col]; int val; Mat Sal=Mat::zeros(src.size(),CV_8UC1 ); Point3_<uchar>* p; for (int i=0;i<row;i++){ for (int j=0;j<col;j++){ p=src.ptr<Point3_<uchar> > (i,j); val=(p->x + (p->y) *2 + p->z)/4; HistGram[val]++; gray[i][j]=val; } } int Dist[256]; int Y,X; int max_gray=0; int min_gray=1<<28; for (Y = 0; Y < 256; Y++) { val = 0; for (X = 0; X < 256; X++) val += abs(Y - X) * HistGram[X]; // 論文公式(9),灰度的距離只有絕對值,這裡其實可以優化速度,但計算量不大,沒必要了 Dist[Y] = val; max_gray=max(max_gray,val); min_gray=min(min_gray,val); } for (Y = 0; Y < row; Y++) { for (X = 0; X < col; X++) { Sal.at<uchar>(Y,X) = (Dist[gray[Y][X]] - min_gray)*255/(max_gray - min_gray); // 計算全圖每個畫素的顯著性 //Sal.at<uchar>(Y,X) = (Dist[gray[Y][X]])*255/(max_gray); // 計算全圖每個畫素的顯著性 } } imshow("sal",Sal); waitKey(0); }
2.AC演算法也挺有意思,利用了類似影象金字塔演算法,在不同緯度(具體實現是用大小不同的均值濾波器過濾影象)與標準影象做差並累加,然後歸一化,實現如下:
void SalientRegionDetectionBasedonAC(Mat &src,int MinR2, int MaxR2,int Scale){ Mat Lab; cvtColor(src, Lab, CV_BGR2Lab); int row=src.rows,col=src.cols; int Sal_org[row][col]; memset(Sal_org,0,sizeof(Sal_org)); Mat Sal=Mat::zeros(src.size(),CV_8UC1 ); Point3_<uchar>* p; Point3_<uchar>* p1; int val; Mat filter; int max_v=0; int min_v=1<<28; for (int k=0;k<Scale;k++){ int len=(MaxR2 - MinR2) * k / (Scale - 1) + MinR2; blur(Lab, filter, Size(len,len )); for (int i=0;i<row;i++){ for (int j=0;j<col;j++){ p=Lab.ptr<Point3_<uchar> > (i,j); p1=filter.ptr<Point3_<uchar> > (i,j); //cout<<(p->x - p1->x)*(p->x - p1->x)+ (p->y - p1->y)*(p->y-p1->y) + (p->z - p1->z)*(p->z - p1->z) <<" "; val=sqrt( (p->x - p1->x)*(p->x - p1->x)+ (p->y - p1->y)*(p->y-p1->y) + (p->z - p1->z)*(p->z - p1->z) ); Sal_org[i][j]+=val; if(k==Scale-1){ max_v=max(max_v,Sal_org[i][j]); min_v=min(min_v,Sal_org[i][j]); } } } } cout<<max_v<<" "<<min_v<<endl; int X,Y; for (Y = 0; Y < row; Y++) { for (X = 0; X < col; X++) { Sal.at<uchar>(Y,X) = (Sal_org[Y][X] - min_v)*255/(max_v - min_v); // 計算全圖每個畫素的顯著性 //Sal.at<uchar>(Y,X) = (Dist[gray[Y][X]])*255/(max_gray); // 計算全圖每個畫素的顯著性 } } imshow("sal",Sal); waitKey(0); }
SalientRegionDetectionBasedonAC(test,test.rows/8,test.rows/2,3);
3.FT演算法 lab空間的均值減去當前畫素值
void SalientRegionDetectionBasedonFT(Mat &src){ Mat Lab; cvtColor(src, Lab, CV_BGR2Lab); int row=src.rows,col=src.cols; int Sal_org[row][col]; memset(Sal_org,0,sizeof(Sal_org)); Point3_<uchar>* p; int MeanL=0,Meana=0,Meanb=0; for (int i=0;i<row;i++){ for (int j=0;j<col;j++){ p=Lab.ptr<Point3_<uchar> > (i,j); MeanL+=p->x; Meana+=p->y; Meanb+=p->z; } } MeanL/=(row*col); Meana/=(row*col); Meanb/=(row*col); GaussianBlur(Lab,Lab,Size(3,3),0,0); Mat Sal=Mat::zeros(src.size(),CV_8UC1 ); int val; int max_v=0; int min_v=1<<28; for (int i=0;i<row;i++){ for (int j=0;j<col;j++){ p=Lab.ptr<Point3_<uchar> > (i,j); val=sqrt( (MeanL - p->x)*(MeanL - p->x)+ (p->y - Meana)*(p->y-Meana) + (p->z - Meanb)*(p->z - Meanb) ); Sal_org[i][j]=val; max_v=max(max_v,val); min_v=min(min_v,val); } } cout<<max_v<<" "<<min_v<<endl; int X,Y; for (Y = 0; Y < row; Y++) { for (X = 0; X < col; X++) { Sal.at<uchar>(Y,X) = (Sal_org[Y][X] - min_v)*255/(max_v - min_v); // 計算全圖每個畫素的顯著性 //Sal.at<uchar>(Y,X) = (Dist[gray[Y][X]])*255/(max_gray); // 計算全圖每個畫素的顯著性 } } imshow("sal",Sal); waitKey(0); }