1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        干貨 | 使用FFT變換自動(dòng)去除圖像中嚴(yán)重的網(wǎng)紋

        共 13304字,需瀏覽 27分鐘

         ·

        2021-03-19 10:16

        點(diǎn)擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

        重磅干貨,第一時(shí)間送達(dá)

        本文轉(zhuǎn)自:opencv學(xué)堂

        這個(gè)課題在很久以前就已經(jīng)有所接觸,不過一直沒有用代碼去實(shí)現(xiàn)過。最近買了一本《機(jī)器視覺算法與應(yīng)用第二版》書,書中再次提到該方法:使用傅里葉變換進(jìn)行濾波處理的真正好處是可以通過使用定制的濾波器來消除圖像中某些特定頻率,例如這些特定頻率可能代表著圖像中重復(fù)出現(xiàn)的紋理。


          在網(wǎng)絡(luò)上很多的PS教程中,也有提到使用FFT來進(jìn)行去網(wǎng)紋的操作,其中最為廣泛的是使用PS小插件FOURIER TRANSFORM,使用過程為:打開圖像--進(jìn)行FFT RGB操作,然后定位到紅色通道,選取通道中除了最中心處的之外的白點(diǎn)區(qū)域,然后填充黑色,在返回綜合通道,點(diǎn)擊IFFT RGB,就OK了,

        針對(duì)這一幅,我曾嘗試在PS中用其他的方法來去背景紋理,可是一般去網(wǎng)的同時(shí)也把相片模糊了,只有FFT去網(wǎng)紋插件能完美去掉相片的網(wǎng)紋而且不損傷畫質(zhì)。


          這個(gè)插件有個(gè)特性,他要求輸入必須是3通道或者4通道的圖,但是用他處理完成后的圖雖然表面上看還是3通道還是4通道的,但是他已經(jīng)失去了彩色信息了,我們注意到他在進(jìn)行FFT RGB操作后,RGB三個(gè)通道中,R通道保存了頻譜圖,G通道了保存了相位圖,B通道為固定值128,頻譜和相位組合在一起,只能回復(fù)一個(gè)通道的信息,因此處理后的圖也只能是一個(gè)顏色了,這是這個(gè)插件的缺陷或者說作為插件的必然性。


          按照這個(gè)思路,如果用戶提供了用于消除與紋理對(duì)應(yīng)的頻率的濾波器,則該過程的一個(gè)大概算法流程如下所示:

        int IM_TextureRemoval(unsigned char *Src, unsigned char *Mask, unsigned char *Dest, int Width, int Height, int Stride)
        {
            int Channel = Stride / Width;
            if ((Src == NULL) || (Dest == NULL))                        return IM_STATUS_NULLREFRENCE;
            if ((Width <= 0) || (Height <= 0))                            return IM_STATUS_INVALIDPARAMETER;
            if ((Channel != 1) && (Channel != 3))                        return IM_STATUS_INVALIDPARAMETER;

            if (Channel == 1)
            {
                Complex    *Data = (Complex*)malloc(Width * Height * sizeof(Complex));

                if (Data == NULL)     return IM_STATUS_OUTOFMEMORY;

                for (int Y = 0; Y < Height; Y++)
                {
                    unsigned char *LinePS = Src + Y * Stride;                //    填充FFT變換的復(fù)數(shù)數(shù)據(jù)
                    Complex *LinePD = Data + Y * Width;
                    for (int X = 0; X < Width; X++)
                    {
                        LinePD[X].Real = LinePS[X];
                        LinePD[X].Imag = 0;
                    }
                }
                IM_FFT2D(Data, Data, Width, Height, false00);            //    FFT變換
                IM_FFTShift(Data, Data, Width, Height);                      //    平移中心到圖像的中心    
                for (int Y = 0; Y < Height; Y++)                             //    FFT變換的結(jié)果乘以用于消除與紋理對(duì)應(yīng)的頻率的濾波器                    
                {
                    unsigned char *LinePS = Mask + Y * Stride;
                    Complex *LinePD = Data + Y * Width;
                    for (int X = 0; X < Width; X++)
                    {
                        LinePD[X].Real *= LinePS[X] * IM_INV255;
                        LinePD[X].Imag *= LinePS[X] * IM_INV255;
                    }
                }
                IM_IFFTShift(Data, Data, Width, Height);                //    在反中心化
                IM_FFT2D(Data, Data, Width, Height, true00);        //    FFT逆變換

                for (int Y = 0; Y < Height; Y++)                        //    轉(zhuǎn)換成圖像
                {
                    Complex *LinePS = Data + Y * Width;
                    unsigned char *LinePD = Dest + Y * Stride;
                    for (int X = 0; X < Width; X++)
                    {
                        LinePD[X] = IM_ClampToByte(LinePS[X].Real);
                    }
                }
                free(Data);
            }
            else
            {

            }
            return IM_STATUS_OK;

        }

        這個(gè)過程也是非常簡單的。


        對(duì)于彩色的圖像,可以把他們先劈成3個(gè)獨(dú)立的通道,然后調(diào)用上述單通道的處理方法,然后在合成。


        不過這個(gè)方法還是有限制的,他能處理的對(duì)象是有非常嚴(yán)重網(wǎng)紋的圖像,我們測試過對(duì)于普通的身份證照片、摩爾紋等是起不到去除作用的,從頻譜上來說,就是要在頻譜上能看到分布在四周處有一些很明顯的獨(dú)立的亮點(diǎn)。這些亮點(diǎn)就對(duì)應(yīng)著紋理的頻率。


          上面的過程需要人工的參與,我們這里進(jìn)行一下擴(kuò)展,嘗試下對(duì)這類圖像進(jìn)行自動(dòng)的紋理去除。這里的核心是找到紋理的頻率,也就是那些白色獨(dú)立的亮點(diǎn)。


        我們看上面的FFT頻譜圖,這種顯示基本上都是對(duì)直接進(jìn)行FFT變換后的浮點(diǎn)數(shù)據(jù)進(jìn)行對(duì)數(shù)變換后,在線性映射到0到255范圍內(nèi)的,有進(jìn)行了log操作,數(shù)據(jù)壓縮了很多,導(dǎo)致頻譜圖的對(duì)比度不是很強(qiáng),也不利于我們分隔出那些亮點(diǎn),如果我們不記性這種操作,而是直接絕對(duì)值Clamp顯示,大概能得到下面的效果: 


        這種效果的FFT圖很明顯更有利于紋理特征的提取。

        下面的步驟就是:OSTU二值化 -- 》膨脹  --》 腐蝕 -- 》 反色  ---》中心核保留  -- 》中值  得到紋理頻率的濾波器。整個(gè)效果如下圖:

        稍微分析下原理吧(也不一定科學(xué))。


        首先二值化,沒啥好說的。二值后,我們看到白色部分有很多零碎的部分,特別是圖像的中心區(qū)域的零碎化對(duì)最后的效果有非常不好的影響(我們必須保持中心部分沒啥變化),所以后續(xù)使用了開操作來改善效果,先膨脹后腐蝕。接著我們反色一下,因?yàn)楹罄m(xù)的濾波器是非中心區(qū)域的白色部分是要變?yōu)楹谏?,第五步,也是比較核心的步驟,我們需要把中心部分的黑色部分變?yōu)榘咨?,因?yàn)檫@部分保留著圖像的大部分信息, 這里我們可以采用基于4領(lǐng)域的區(qū)域生長法,因?yàn)樵陬l譜中的中心點(diǎn),這一點(diǎn)二值后肯定是白色的,在反色后就是白色,就以這一點(diǎn)為種子點(diǎn),向四周進(jìn)行區(qū)域生長,這樣就可以把中心處的黑色反色過來,而其他地方的黑色保持不變。


        第五步的中值,或者可以用其他模糊來代替,也是有點(diǎn)必要的,對(duì)于有些圖像,經(jīng)過前面的處理后,有些核心的線(垂直或者水平方向)也被標(biāo)記為黑色的了,正在處理完成的圖像中會(huì)帶來原本沒有的新條紋。

        上述過程先關(guān)的函數(shù)如下所示:

        //    根據(jù)頻譜圖預(yù)估紋理的頻譜蒙版區(qū)域,支持InPlace操作
        int IM_GetTextureMask(unsigned char *Src, unsigned char *Dest, int Width, int Height, int Stride)
        {
            int Channel = Stride / Width;
            if ((Src == NULL) || (Dest == NULL))                return IM_STATUS_NULLREFRENCE;
            if ((Width <= 0) || (Height <= 0))                    return IM_STATUS_INVALIDPARAMETER;
            if (Channel != 1)                                    return IM_STATUS_INVALIDPARAMETER;
            int Status = IM_STATUS_OK;
            unsigned char *Temp = (unsigned char *)malloc(Height * Stride * sizeof(unsigned char));
            if (Temp == NULL){ Status = IM_STATUS_OUTOFMEMORY;        goto FreeMemory; }

            int Threshold = 0;
            Status = IM_GetOSTUThreshold(Src, Width, Height, Stride, Threshold);    //    使用OSTU方法二值化
            if (Status != IM_STATUS_OK)        goto FreeMemory;
            Status = IM_Threshold(Src, Temp, Width, Height, Stride, Threshold);        //    二值化
            if (Status != IM_STATUS_OK)        goto FreeMemory;
            Status = IM_Dilate(Temp, Dest, Width, Height, Stride, 2false);        //    先膨脹下(最大值),注意膨脹和腐蝕函數(shù)不支持InPlace操作
            if (Status != IM_STATUS_OK)        goto FreeMemory;
            Status = IM_Erode(Dest, Temp, Width, Height, Stride, 2false);            //    然后在腐蝕(最小值),恢復(fù)原來的差不多大小,但是這樣中心區(qū)域不相鄰的點(diǎn)就少了很多
            if (Status != IM_STATUS_OK)        goto FreeMemory;
            Status = IM_Invert(Temp, Dest, Width, Height, Stride);                    //    這個(gè)時(shí)候的圖,紋理的頻譜和其他核心能量區(qū)域都還是白色,為后續(xù)的處理需要先反色
            if (Status != IM_STATUS_OK)        goto FreeMemory;
            Status = IM_InvertCenter(Dest, Temp, Width, Height, Stride);            //    把中心的能量區(qū)域保留(白色),其他的紋理的頻譜刪除(黑色)
            if (Status != IM_STATUS_OK)        goto FreeMemory;
            Status = IM_MedianBlur(Temp, Dest, Width, Height, Stride, 150);        //    執(zhí)行半徑為1的中值,這樣可能可以減少部分垂直或者水平的核心能力被刪除
            if (Status != IM_STATUS_OK)        goto FreeMemory;

        FreeMemory:
            if (Temp != NULL)    free(Temp);
            return Status;
        }

        我們注意到,上面的操作對(duì)紋理處頻率處對(duì)應(yīng)的濾波器系數(shù)都為0了,也就是這一塊的信息全部被消除了,當(dāng)然實(shí)際操作時(shí)也可以稍微羽化一下,對(duì)最后的結(jié)果影響不大。


        根據(jù)上述的步驟,有選擇性的處理了幾幅圖,結(jié)果如下所示:

        可以看出,雖然能再一定程度上去除網(wǎng)紋,但是也就有一些去除的不完全,這主要還是因?yàn)樽詣?dòng)提取的濾波器還是不夠準(zhǔn)確,要想獲取更為理想的結(jié)果,必須手動(dòng)的予以修繕。


          對(duì)于常規(guī)的圖片,或者說紋理信息不明顯的圖,及時(shí)執(zhí)行了上面的去紋理,圖片也基本上沒有什么變化,因?yàn)榘凑丈鲜龇椒ǖ玫降臑V波器基本都為白色。


        下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
        在「小白學(xué)視覺」公眾號(hào)后臺(tái)回復(fù):擴(kuò)展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

        下載2:Python視覺實(shí)戰(zhàn)項(xiàng)目52講
        小白學(xué)視覺公眾號(hào)后臺(tái)回復(fù):Python視覺實(shí)戰(zhàn)項(xiàng)目,即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計(jì)數(shù)、添加眼線、車牌識(shí)別、字符識(shí)別、情緒檢測、文本內(nèi)容提取、面部識(shí)別等31個(gè)視覺實(shí)戰(zhàn)項(xiàng)目,助力快速學(xué)校計(jì)算機(jī)視覺。

        下載3:OpenCV實(shí)戰(zhàn)項(xiàng)目20講
        小白學(xué)視覺公眾號(hào)后臺(tái)回復(fù):OpenCV實(shí)戰(zhàn)項(xiàng)目20講,即可下載含有20個(gè)基于OpenCV實(shí)現(xiàn)20個(gè)實(shí)戰(zhàn)項(xiàng)目,實(shí)現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

        交流群


        歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器自動(dòng)駕駛、計(jì)算攝影、檢測、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請(qǐng)按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~


        瀏覽 74
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            超碰在线进入 | 日本边添边摸边做边爱的主演 | 国产高清无码毛片 | 网站黄色小视频 | 好大好粗好爽视频 | 荫蒂被男人添的好舒服的 | 国产男女无遮挡猛进猛出30分钟 | 91免费看黄软件 | 红桃视频乱码一区二区三区 | 边吃奶边插 |