1. 程式人生 > >Ft(Frequency-tuned)演算法進行顯著性檢測 opencv實現(C++)

Ft(Frequency-tuned)演算法進行顯著性檢測 opencv實現(C++)

FT演算法來自文獻:《Frequency-tuned Salient Region Detection》

FT演算法由Achanta等提出,利用顏色特徵的中央-周邊運算元來得到顯著圖。其求解過程非常簡單:

其演算法原理如下圖所示:
流程圖

原理比較簡單:

作者主要利用的是顏色特徵和亮度特徵。

  1. 對影象img進行高斯濾波得到gfrgb;
  2. 將影象imgrgb由RGB顏色空間轉換為LAB顏色空間imglab;
  3. 對轉換後的影象imglab 的L,A,B三個通道的影象分別取均值得到lm,am,bm;
  4. 計算顯著值,即對分別對三個通道的均值影象和濾波得到的影象取歐氏距離並求和;
  5. 利用最大值對顯著圖歸一化。

作者主頁開源了其matlab程式碼,如下:

im=imread('./srcimgs/test.jpg');      %讀圖

gfrgb = imfilter(im, fspecial('gaussian', 3, 3), 'symmetric', 'conv'); %高斯濾波,核3*35*5

%gfrgb = im;
cform = makecform('srgb2lab');%顏色空間轉換,RGB--->Lab空間,獲取一個轉換模板cform

lab = applycform(gfrgb,cform);%顏色空間轉換,完成RGB--->Lab空間轉換



l = double(lab(:,:,1
));%L通道 lm = mean(mean(l));%整幅圖片的l均值 a = double(lab(:,:,2)); am = mean(mean(a));%整幅圖片的a均值 b = double(lab(:,:,3)); bm = mean(mean(b));%整幅圖片的b均值 sm = (l-lm).^2 + (a-am).^2 + (b-bm).^2;%計算畫素的顯著度 s=max(sm(:)); %顯著圖中最大值 sa=sm./s; %歸一化 imshow(sa); %顯

matlab程式碼執行結果:

原圖:

這裡寫圖片描述

FT顯著檢測結果:
這裡寫圖片描述

嘗試用opencv實現了下,程式碼比較簡單,其中轉lab空間的部分直接呼叫了opencv中的cvtcolor函式,不知道為什麼搜其它部落格很少直接這麼做的,我輸入了一張測試圖進行測試,轉出的lab空間中的lab三通道值與作者提供的matlab程式碼中的數值大致相同,不同應該是因為計算時浮點數不同。

實現環境:VS2013 + opencv2.4.9

程式碼:

/*===========================================================================
[email protected], Harbin Institute of Technology
Date:Apr,13,2018
Contact:[email protected]
blog: https://blog.csdn.net/yinhuan1649
===========================================================================*/
#include <iostream>
#include <highgui.h>
# include <opencv2/opencv.hpp> 
#include <fstream> 
using namespace cv;
using namespace std;

void writeMatToFile(cv::Mat& m, const char* filename)        //把矩陣寫入txt檔案
{
    std::ofstream fout(filename);

    if (!fout)
    {
        std::cout << "File Not Opened" << std::endl;
        return;
    }

    for (int i = 0; i<m.rows; i++)
    {
        for (int j = 0; j<m.cols; j++)
        {
            fout << m.at<double>(i, j) << "\t";
        }
        fout << std::endl;
    }

    fout.close();
}

int main(){
    Mat srcimg,grgbimg, labimg;

    srcimg = imread("./srcimgs/test.jpg");         
    int height = srcimg.rows;
    int width = srcimg.cols;
    GaussianBlur(srcimg, srcimg, Size(3, 3), 0, 0, BORDER_REFLECT);            // 高斯模糊
    cvtColor(srcimg, labimg, CV_BGR2Lab);                                      //轉到lab空間

    cv:Scalar tempVal = cv::mean(labimg);                                      //求各通道均值

    double lmean = tempVal.val[0];
    double amean = tempVal.val[1];
    double bmean = tempVal.val[2];

    Mat salientMap = Mat::zeros(height, width, CV_64F);                        //定義顯著圖,因為是double型別,所以在這裡初始化型別為CV_64F
    for (int i = 0; i < height; i++){
        for (int j = 0; j < width; j++){
            //顯著值計算,對應matlab程式碼中sm = (l-lm).^2 + (a-am).^2 + (b-bm).^2;
            salientMap.at<double>(i, j) = ((double)labimg.at<Vec3b>(i, j)[0] - lmean)*((double)labimg.at<Vec3b>(i, j)[0] - lmean)
                                        + ((double)labimg.at<Vec3b>(i, j)[1] - amean)*((double)labimg.at<Vec3b>(i, j)[1] - amean)
                                        + ((double)labimg.at<Vec3b>(i, j)[2] - bmean)*((double)labimg.at<Vec3b>(i, j)[2] - bmean);

        }
    }

    //double max, min;
    //cv::Point min_loc, max_loc;
    //cv::minMaxLoc(salientMap, &min, &max, &min_loc, &max_loc);//求mat中最值
    //cout << "max:"<< max << endl;


    //for (int i = 0; i < salientMap.rows; i++)
    //{
    //  for (int j = 0; j < salientMap.cols; j++)
    //  {
    //      salientMap.at<double>(i, j) = salientMap.at<double>(i, j) / max;
    //  }
    //}


    normalize(salientMap, salientMap, 1.00, 0.00, NORM_MINMAX);                // 1值歸一化
    writeMatToFile(salientMap, "F:\\test.txt");
    cout << "yes!!" << endl;
    //cout << "salientMap:" << salientMap << endl;
    imshow("salientMap:", salientMap);
    waitKey();

    system("pause");
    return 0;
}

opencv+vs FT顯著圖檢測結果:

這裡寫圖片描述

matlab(上)與opencv(下)對比:

這裡寫圖片描述

如有錯誤之處敬請指正!

相關推薦

FtFrequency-tuned演算法進行顯著檢測 opencv實現C++

FT演算法來自文獻:《Frequency-tuned Salient Region Detection》 FT演算法由Achanta等提出,利用顏色特徵的中央-周邊運算元來得到顯著圖。其求解過程非常簡單: 其演算法原理如下圖所示: 原理比較簡單:

讀取檔案內的資料數字進行三種排序,1快速排序2歸併排序3希爾排序

#include<iostream> #include<fstream> #include<stdlib.h> int n1=0; using namespace std; void Merge(int a[], i

基於KNN分類演算法手寫數字識別的實現——構建KD樹

上一篇已經簡單粗暴的建立了一個KNN模型對手寫圖片進行了識別,所以本篇文章採用構造KD樹的方法實現手寫數字的識別。 (一)構造KD樹 構造KD樹的基本原理網上都有介紹,所以廢話不多說,直接上程式碼。 #Knn KD_Tree演算法 import math from

排序演算法1——圖解氣泡排序及其實現三種方法,基於模板及函式指標

排序演算法1——圖解氣泡排序及其實現(三種方法,基於模板及函式指標) 排序演算法2——圖解簡單選擇排序及其實現 排序演算法3——圖解直接插入排序以及折半(二分)插入排序及其實現 排序演算法4——圖解希爾排序及其實現 排序演算法5——圖解堆排序及其實現 排序演算法6——圖解歸併排序及其遞迴與非

K近鄰KNN演算法、KD樹及其python實現

1、k近鄰演算法 1.1 KNN基本思想 k近鄰法是基本且簡單的分類與迴歸方法,即對於輸入例項,依據給定的距離度量方式(歐式距離),以及選擇合適的k值(交叉驗證),在樣本集中找到最近鄰新例項的k個樣例,通過k個最近鄰樣例的類別表決出新例項的類別(多數表決)。

多層感知機MLP演算法原理及Spark MLlib呼叫例項Scala/Java/Python

多層感知機 演算法簡介:         多層感知機是基於反向人工神經網路(feedforwardartificial neural network)。多層感知機含有多層節點,每層節點與網路的下一層節點完全連線。輸入層的節點代表輸入資料,其他層的節點通過將輸入資料與層上節點

基於哈夫曼壓縮演算法的壓縮與解壓實現Java

如果需要對一個檔案進行壓縮,第一步是提取出檔案中的內容資訊;第二步是對其中的字元等進行統計,獲得壓縮編碼;第三步是把壓縮編碼及解壓檔案需要的資訊存入一個檔案(或者生成新檔案並存入)。這樣對檔案的壓縮就完成了。 下面就是檔案的解壓,第一步還是讀入檔案,即從前面生

MLlib--多層感知機MLP演算法原理及Spark MLlib呼叫例項Scala/Java/Python

來源:http://blog.csdn.net/liulingyuan6/article/details/53432429 多層感知機 演算法簡介:         多層感知機是基於反向人工神經網路(feedforwardartificial neural net

java 非阻塞演算法在併發容器中的實現ConcurrentLinkedQueue原始碼

簡介 非阻塞演算法在更細粒度的層面協調爭用,它比傳統的鎖有更高的併發性。隨著非阻塞演算法在 Java 中的應用越來越廣泛,java.concurrent 包中用非阻塞演算法實現的併發容器也越來越多,ConcurrentLinkedQueue 就是其中的一個重要

隨機森林迴歸Random Forest演算法原理及Spark MLlib呼叫例項Scala/Java/python

隨機森林迴歸 演算法介紹:        隨機森林是決策樹的整合演算法。隨機森林包含多個決策樹來降低過擬合的風險。隨機森林同樣具有易解釋性、可處理類別特徵、易擴充套件到多分類問題、不需特徵縮放等性質。 隨機森林分別訓練一系列的決策樹,所以訓練過程是並行的。因演算法中加入隨機

梯度迭代樹GBDT演算法原理及Spark MLlib呼叫例項Scala/Java/python

梯度迭代樹 演算法簡介:         梯度提升樹是一種決策樹的整合演算法。它通過反覆迭代訓練決策樹來最小化損失函式。決策樹類似,梯度提升樹具有可處理類別特徵、易擴充套件到多分類問題、不需特徵縮放等性質。Spark.ml通過使用現有decision tree工具來實現。

演算法學習】B-Tree程式設計實現C++模板類封裝

B-Tree模擬程式設計實現。採用C++模板類封裝。參考《演算法導論(第二版)》第18章 B樹。 實現了B樹的搜尋、插入和刪除的重要操作。 歡迎交流和討論,如有錯誤,還請指出~(E-Mali:[email protected]) BTree.h: //B-

uc/os-II的記憶體改進與實現TLSF演算法的詳解,移植實現

上一節講到了TLSF的資料結構,下面繼續哈。 TLSF用兩個層次的分類對不同尺寸的記憶體塊進行分類。第一層次的類別目錄為2n,n為4,5,……,31的整數,稱為FLI(First-level Segregated Fit)。每一個FLI類別又根據第二層的SLI細分為2SLI

演算法】字串反轉的多種實現 java程式碼實現

原本還想再寫一個不使用額外記憶體的,發現貌似java實現不了, 如果哪位大神能實現歡迎補充 package com.billkang.algorithm; /** * 字串反轉 * * @au

影象顯著檢測——時域分析譜殘差法、相位譜法

1.基於譜殘差法的顯著性檢測 (Saliency Detection: A Spectral Residual Approach) 給定一幅影象,I(x)首先計算其2維離散傅立葉變換,將其從空間域轉換到頻域,對幅值取對數後得到log譜L(f): 式中F代表2維離散

GMM混合高斯背景建模C++結合Opencv實現內附Matlab實現

最近在做視訊流檢測方面的工作,一般情況下這種視訊流檢測是較複雜的場景,比如交通監控,或者各種監控攝像頭,場景比較複雜,因此需要構建背景影象,然後去檢測場景中每一幀動態變化的前景部分,GMM高斯模型是建模的一種方法,關於高斯建模的介紹有很多部落格了,大家可以去找一找,本篇部落格主要依賴於上

Android:答題APP的設計與實現mysql+jsp+Android Android:答題APP的設計與實現mysql+jsp+Android

Android:答題APP的設計與實現(mysql+jsp+Android) 還沒有整理完,待續…… 學校開了Android課,最後讓交一個大作業。正好拿來練練手,記錄下思路。也希望能給有需要的朋友們一些幫助。恩,純小白教程,大神們可以繞路了。 作業的題目是這樣的: 考試A

FPGA邊沿檢測Verilog實現包含上升沿,下降沿,雙邊沿

寫在最前面:2019屆秋招進行中。。。希望能拿到自己滿意的offer。。。楊超越附體(手動狗頭)。。。 網上搜了一下,結合自己總結的。首先介紹一下基本的原理。 脈衝邊沿的特性:兩側電平發生了變化 思路:設計兩個或多個一位的暫存器,用來接收被檢測的訊號,系統時鐘來

影象處理基礎及OpenCV實現

最近學習數字影象處理基礎及OpenCV實現這本書,寫一點東西記錄所學的內容。。 一、 開啟影象與視訊 開啟影象 用到了OpenCV中的結構體IplImage, 函式IplImage* cvLoadImage( const char* filename, int

【 MATLAB 】DFT的性質討論序列的迴圈移位及其 MATLAB 實現時域方法

如果一個N點序列在任一方向上移位,那麼其結果都不在是位於 0 < = n <= N-1之間。因此,需要進行下面的操作: 為了形象化,可以設想將序列x(n)放在一個圓上,現在將這個圓旋轉