1. 程式人生 > >影象基本知識整理(3)——影象的正交變換

影象基本知識整理(3)——影象的正交變換

//小波基
const double hCoef[10][20] =
{
    { .707106781187,  .707106781187},
    { .482962913145,  .836516303738,  .224143868042, -.129409522551 },
    { .332670552950,  .806891509311,  .459877502118, -.135011020010, -.085441273882,  .035226291882 },
    { .230377813309,  .714846570553,  .630880767930, -.027983769417,-.187034811719,  .030841381836,  .032883011667, -.010597401785 },
    { .160102397974,  .603829269797,  .724308528438,  .138428145901, -.242294887066,-.032244869585,  .077571493840, -.006241490213, -.012580751999,  .003335725285 },
    { .111540743350,  .494623890398,  .751133908021,  .315250351709, -.226264693965,
    -.129766867567,  .097501605587,  .027522865530, -.031582039318,  .000553842201,
    .004777257511, -.001077301085 },
    { .077852054085,  .396539319482,  .729132090846,  .469782287405, -.143906003929,
    -.224036184994,  .071309219267,  .080612609151, -.038029936935, -.016574541631,
    .012550998556,  .000429577973, -.001801640704,  .000353713800 },
    { .054415842243,  .312871590914,  .675630736297,  .585354683654, -.015829105256,
    -.284015542962,  .000472484574,  .128747426620, -.017369301002, -.044088253931,
    .013981027917,  .008746094047, -.004870352993, -.000391740373,  .000675449406,
    -.000117476784 },
    { .038077947364,  .243834674613,  .604823123690,  .657288078051,  .133197385825,
    -.293273783279, -.096840783223,  .148540749338,  .030725681479, -.067632829061,
    .000250947115,  .022361662124, -.004723204758, -.004281503682,  .001847646883,
    .000230385764, -.000251963189,  .000039347320 },
    { .026670057901,  .188176800078,  .527201188932,  .688459039454,  .281172343661,
    -.249846424327, -.195946274377,  .127369340336,  .093057364604, -.071394147166,
    -.029457536822,  .033212674059,  .003606553567, -.010733175483,  .001395351747,
    .001992405295, -.000685856695, -.000116466855,  .000093588670, -.000013264203 }
};
//一維小波變換
BOOL DWTStep_1D(double* pDbSrc, int nCurLevel,int nInv, int nStep,int nSupp)
{
    double s = sqrt((double)2);
    // 獲得小波基的指標
    double* h = (double*)hCoef[nSupp-1];
    // 確認當前層數有效
    ASSERT(nCurLevel>=0);
    // 計算當前層數的長度
    int CurN = 1<<nCurLevel;
    if (nInv) CurN <<= 1;
    // 確認所選擇的小波基和當前層數的長度有效
    if (nSupp<1 || nSupp>10 || CurN<2*nSupp)
        return FALSE;
    // 分配臨時記憶體用於存放結果
    double *ptemp = new double[CurN];
    if (!ptemp) return FALSE;
    double    s1, s2;
    int    Index1, Index2;
    // 判斷是進行DWT還是IDWT
    if (!nInv)
    {    // DWT
        Index1=0;
        Index2=2*nSupp-1;
        // 進行卷積,其中s1為低頻部分,s2為高頻部分的結果
        for (int i=0; i<CurN/2; i++)
        {    
            s1 = s2 = 0;
            double t = -1;
            for (int j=0; j<2*nSupp; j++, t=-t)
            {
                s1 += h[j]*pDbSrc[(Index1 & CurN-1) * nStep];
                s2 += t*h[j]*pDbSrc[(Index2 & CurN-1) * nStep];
                Index1++;
                Index2--;
            }
            // 將結果存放在臨時記憶體中
            ptemp[i] = s1/s;
            ptemp[i+CurN/2] = s2/s;
            Index1 -= 2*nSupp;
            Index2 += 2*nSupp;
            Index1 += 2;
            Index2 += 2;
        }
    }
    // 否則進行IDWT
    else
    {    // IDWT
        Index1 = CurN/2;
        Index2 = CurN/2-nSupp+1;
        // 進行卷積,其中其中s1為低頻部分,s2為高頻部分的結果
        for (int i=0; i<CurN/2; i++)
        {
            s1 = s2 = 0;
            int Index3 = 0;
            for (int j=0; j<nSupp; j++)
            {
                s1 += h[Index3]*pDbSrc[(Index1 & CurN/2-1) * nStep]
                +h[Index3+1]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];
                s2 += h[Index3+1]*pDbSrc[(Index1 & CurN/2-1) * nStep]
                -h[Index3]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];

                Index3+=2;
                Index1--,        Index2++;
            }
            // 將結果存入臨時記憶體
            ptemp[2*i] = s1*s;
            ptemp[2*i+1] = s2*s;
            Index1 += nSupp;
            Index2 -= nSupp;
            Index1++;
            Index2++;
        }
    }
    // 將結果存入源影象中
    for (int i=0; i<CurN; i++)
        pDbSrc[i*nStep] = ptemp[i];
    // 釋放臨時記憶體,並返回
    delete[] ptemp;
    return TRUE;
}
//二維小波變換
BOOL DWTStep_2D(double* pDbSrc, int nCurWLevel, int nCurHLevel,
                int nMaxWLevel, int nMaxHLevel, int nInv, int nStep, int nSupp)
{
    // 計算影象的長度和寬度(2次冪對齊)
    int W = 1<<nMaxWLevel, H = 1<<nMaxHLevel;
    // 計算當前分解的影象的長度和寬度
    int CurW = 1<<nCurWLevel, CurH = 1<<nCurHLevel;
    // 判斷是進行DWT還是IDWT
    if (!nInv)
    {    
        int i = 0;
        // 對行進行一維DWT
        for (i=0; i<CurH; i++)
            if (!DWTStep_1D(pDbSrc+(int)i*W*nStep, nCurWLevel, nInv, nStep, nSupp)) return FALSE;
        // 對列進行一維DWT
        for (i=0; i<CurW; i++)
            if (!DWTStep_1D(pDbSrc+i*nStep, nCurHLevel, nInv, W*nStep, nSupp)) return FALSE;
    }
    // 否則進行IDWT
    else
    {
        // 計算當前變換的影象的長度和寬度
        CurW <<= 1;
        CurH <<= 1;
        int i = 0;
        // 對列進行IDWT
        for (i=0; i<CurW; i++)
            if (!DWTStep_1D(pDbSrc+i*nStep, nCurHLevel, nInv, W*nStep, nSupp)) return FALSE;
        // 對行進行IDWT
        for (i=0; i<CurH; i++)
            if (!DWTStep_1D(pDbSrc+(int)i*W*nStep, nCurWLevel, nInv, nStep, nSupp)) return FALSE;
    }
    // 返回
    return TRUE;
}
//資料轉換
BYTE FloatToByte(double f)
{
    if (f<=0) return (BYTE)0;
    else if (f>=255) return (BYTE)255;
    else return (BYTE)(f+0.5);
}
//資料轉換
char FloatToChar(double f)
{
    if (f>=0)
        if (f>=127.0)
            return (char)127;
        else return (char)(f+0.5);
    else
        if (f<=-128)
            return (char)-128;
        else return -(char)(-f+0.5);
}
//資料轉換
int Log2(int n)
{
    int rsl = 0;
    while (n >>= 1) rsl++;
    return rsl;
}
//影象小波變換
BOOL DIBDWTStep(LPSTR lpDIBBits,double*m_pDbImage, int nWidth,int nHeight, int nInv,int m_nDWTCurDepth,int m_nSupp)
{
    // 迴圈變數
    int i, j;
    // 獲取變換的最大層數
    int nMaxWLevel = Log2(nWidth);
    int nMaxHLevel = Log2(nHeight);
    int nMaxLevel;
    if (nWidth == 1<<nMaxWLevel && nHeight == 1<<nMaxHLevel)
        nMaxLevel = min(nMaxWLevel, nMaxHLevel);
    // 臨時變數
    double    *pDbTemp;
    BYTE    *pBits;
    // 如果小波變換的儲存記憶體還沒有分配,則分配此記憶體
    if(!m_pDbImage){            
        m_pDbImage = new double[nWidth*nHeight];
        if (!m_pDbImage)    return FALSE;
        // 將影象資料放入m_pDbImage中
        for (j=0; j<nHeight; j++)
        {
            pDbTemp = m_pDbImage + j*nWidth;
            pBits = (unsigned char *)lpDIBBits + (nHeight-1-j)*nWidth;        
            for (i=0; i<nWidth; i++)
                pDbTemp[i] = pBits[i];
        }
    }
    // 進行小波變換(或反變換)
    if (!DWTStep_2D(m_pDbImage, nMaxWLevel-m_nDWTCurDepth, nMaxHLevel-m_nDWTCurDepth,
        nMaxWLevel, nMaxHLevel, nInv, 1, m_nSupp))
        return FALSE;
    // 如果是反變換,則當前層數減1
    if (nInv)
        m_nDWTCurDepth --;
    // 否則加1
    else
        m_nDWTCurDepth ++;
    // 然後,將資料拷貝回原CDib中,並進行相應的資料轉換
    int lfw = nWidth>>m_nDWTCurDepth, lfh = nHeight>>m_nDWTCurDepth;
    for (j=0; j<nHeight; j++)
    {
        pDbTemp = m_pDbImage + j*nWidth;
        pBits = (unsigned char *)lpDIBBits + (nHeight-1-j)*nWidth;
        for (i=0; i<nWidth; i++)
        {
            if (j<lfh && i<lfw)
                pBits[i] = FloatToByte(pDbTemp[i]);
            else
                pBits[i] = BYTE(FloatToChar(pDbTemp[i]) ^ 0x80);            
        }
    }
    // 返回
    return TRUE;
}

相關推薦

影象基本知識整理3——影象變換

//小波基 const double hCoef[10][20] = {     { .707106781187,  .707106781187},     { .482962913145,  .836516303738,  .224143868042, -.129409522551 },     { .33

影象處理基本概念筆記3

著作權歸作者所有。 商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。 作者:cvvision 連結:http://www.cvvision.cn/8910.html 來源:CV視覺網 三、 31、機器視覺基本功能 測量、定位、識別、檢測 32、英寸 1英寸=25.4 mm 但是在CCD中間

OpenCV學習筆記3影象的通道channels問題

(1)影象的通道指的是什麼?是不是灰度圖的通道數為1,彩色圖的通道為3?(zhuker) 正確!  基本上,描述一個畫素點,如果是灰度,那麼只需要一個數值來描述它,就是單通道。  如果一個畫素點,有RGB三種顏色來描述它,就是三通道。(ollydbg23) (2)對於

C/C++ BMP24位真彩色影象處理3------影象の放大縮小雙線性插值

    影象的放大縮小其實是一回事,都是先建立一張空白目標影象(放大縮小後的影象),其大小就是想要放大縮小後所得到的影象大小。建立影象後我們並不知道這張影象裡面的各個畫素點RGB(或灰度)值是多少,這個時候就需要經過一個演算法去算目標影象的畫素點RGB(或灰度)值。基本上所

Web優化躬行記3——影象和網路

一、影象 1)響應式影象   瀏覽器根據螢幕大小、裝置畫素比、橫豎屏自動載入合適的影象。   響應式的功能可以通過srcset和sizes兩個新屬性實現。   前者可指定選擇的影象以及其大小,後者會定義一組媒體條件並宣告填充的寬度。   在下面的示例中(線上檢視效果),瀏覽器會先檢視裝置寬度,然後檢查size

OpenCV計算機視覺學習3——影象灰度線性變換與非線性變換對數變換,伽馬變換

如果需要處理的原圖及程式碼,請移步小編的GitHub地址   傳送門:請點選我   如果點選有誤:https://github.com/LeBron-Jian/ComputerVisionPractice   下面主要學習影象灰度化的知識,結合OpenCV呼叫 cv2.cvtColor()函式實現影象灰度化,

Java基礎知識整理

顯式 sys 轉換 強制 print pri 字符 parse ger Java開發環境JDK(Java編輯器、Java運行工具(JRE作用)、Java文檔生成工具、Java打包工具) 1.Java是嚴格區分大小寫的。2.Java程序中一句連續的字符串不能分開在兩行書寫,

《HTML5與CSS3權威指南》知識整理1

scrip 自動驗證 視頻 err ide p s sil html5 oca 《HTML5與CSS3權威指南》知識點整理(1) 1、新增標簽 新增語義化標簽。 <header> 定義 section 或 page 的頁眉。 <nav>定義

ES6知識整理6--Symbol函數

edi sans tap BE undefine tle cti type 很多 (文章會同步到博客園,技術類文章還是該讓搜索引擎察覺比較好)symbol是js的第7種數據類型:7種分別是:undefined、null、boolean(布爾)、string(字符串)、num

ES6知識整理7--Set和Map數據結構

ora ear 踏實 9.png 叠代 數據 edi KS 返回鍵 (文章會同步到博客園,技術類文章還是該讓搜索引擎察覺比較好)Set構造函數初始化一個值不重復的數組,適合做數組去重。2種數組去重的方法:這裏再說下Array.from(),表示以一個類數組||可叠代對象,創

圖像處理基本知識總結

空間 彩色 最終 圖像處理 邊緣 不同的 byte 一個 分析法 筆試題知識點 1、存儲一副大小為1024×1024,256個灰度的圖像,需要(8M)byte。 256是2的8次方,即8位,8個bit,1個字節;等於1024*1024*8 (bit)=8M(bit)。 2、

實習期間的一些思考整理32018.4.12~4.13

com alt 榮耀 8.4 基本 戰鬥機 那種 spa 失去 青雲訣遊戲體驗日報-2018.4.12 今日關鍵點:核心玩法 青雲訣的核心玩法是“戰鬥”、“成長”、“探索”(這三點也是RPG類型的要素),側重於成長。 我是這樣想的,要想找出核心玩法是什麽,就要看哪些玩法沒了

ldap 基本名詞解釋3

alc man 必須 人的 inf sco iar led 代碼 名詞解釋 Objectclass   LDAP對象類,是LDAP內置的數據模型。每種objectClass有自己的數據結構,比如我們有一種叫“電話薄”的objectClass,肯定會內置很多屬性(attrib

自然場景文字處理論文整理3Mask TextSpotter

這篇論文是2018年7月6號出來的,對於任意形狀的自然文字檢測識別效果非常好。 paper:https://arxiv.org/abs/1807.02242 目前無相關原始碼 1.摘要簡介 在本文中,我們提出了一個名為Mask TextSpotter的文字監視器,它可以檢測和

jQuery學習整理--3jQueryHTML

1.jQuery - 獲取內容和屬性 jQuery DOM 操作 DOM = Document Object Model(文件物件模型) DOM 定義訪問 HTML 和 XML 文件的標準: “W3C 文件物件模型獨立於平臺和語言的介面,允許程式和指令碼動態訪問和更新文件

Docker入門基礎學習整理3

Docker常用操作 Docker在只讀層上新增一個可寫層, registry用於儲存映象 一個映象可以有多個Tag,一個Tag只能有一個映象 6種名稱空間:UTS.User,mount,IPC,Pid,Net 使用docker build建立映象 格式 dockersbu

MySQL知識整理

   MySQL基礎知識   資料庫相關概念 DB:database,即是資料庫,裡面儲存了有組織的規範資料。 DBMS:database management system,即是資料庫管理系統,簡稱資料庫軟體、資料庫產品,資料庫是通過DBMS建立和

【JAVA面試】java面試題整理3

                                     java面試題整理(3) JAVA常考點3 目錄 1. 講下JAVA的執行時區域 回答:執行時資料區整體分為兩類 執行緒私有和執行

Spring5知識整理

Spring的表示式語言spEL Spring表示式語言(SpEL):是一個支援執行時查詢和操作物件圖的強大表示是語言,是一種可以與一個基於spring的應用程式中的執行時物件互動的東西。總得來說SpEL表示式是一種簡化開發的表示式,通過使用表示式來簡化開發,減少一些邏輯、配置的編寫。

CCNA學習筆記 基礎知識回顧3

一、 OSI參考模型 七層 應用層     抽象語言---->編碼 表示層     編碼---->二進位制 會話層     應用程式提供會話地址 類似:QQ號碼 *上三層就是應用程式對資訊程序加工處理,直到可以被傳輸(相當於OSI"工廠"生產貨物的車間); 傳輸層     分