FPGA實現視頻圖像的水印添加


  圖像水印到處可見,如微博圖片右下角會有原創者 ID 水印,很多 PDF 文件中也夾有水印,而視頻圖像同樣可以添加水印,最著名的視頻圖像水印便是電視台的標志了。圖像水印在文化產權上起到非常重要的作用,對所有者的權益起到一定的保護。

  數字圖像的水印疊加公式為:f x = (1-a)f + aw
  未加水印的圖像表示為 f,水印表示為 w,常數 a 控制水印和襯底圖像的相對可見性。如果 a 為 1,則水印是不透明的,並且襯底圖像完全是暗的;隨着 a 接近 0,會逐漸看到更多的襯底圖像和更少的水印,通常 a 在 0 和 1 之間。
  本篇博客整理一下如何使用 FPGA 為視頻圖像添加自定義的水印圖案。
 
一、水印圖像
  水印圖像可以自己找一張喜歡的圖片或字符,但不要太大,否則就喧賓奪主了。如下是我本次實驗選取的水印圖案:
  這是我博客的頭像,我將其分辨率改為 50x50。
 
二、圖像轉mif文件
  網上很多圖像轉 16位 mif 文件的小軟件,當然如果你 MATLAB 學的好,也可以用 MATLAB 來實現。此次我使用的是正點原子開發的 “PicToMif_V1.0.exe”。
 
三、rom生成
  rom的位寬設置為 16,深度設置為 2500(水印圖像分辨率),然后把第二步生成的 mif 文件包含進去即可,不添加鎖存器,讓數據輸出的延時為1個時鍾周期,rden信號也不需要,有讀地址就夠了。
 
四、添加水印圖案的設計
1、直接添加水印
  可以單獨設計一個 .v 模塊為水印圖案模塊,這個設計代碼量小,我直接寫在頂層模塊的 TFT_driver 之后,連接管腳之前。代碼如下所示:
//==========================================================================
//==                        TFT
//==========================================================================
TFT_driver u_TFT_driver 
(
    .clk                    (clk_10m                ), 
    .rst_n                  (rst_n                  ),
    .TFT_req                (rd_en                  ),
    .TFT_x                  (TFT_x                  ),
    .TFT_y                  (TFT_y                  ),
    .TFT_din                (rd_data                ),
    .TFT_clk                (TFT_clk                ),
    .TFT_de                 (TFT_de                 ),
    .TFT_pwm                (TFT_pwm                ),
    .TFT_hsync              (TFT_hsync              ),
    .TFT_vsync              (TFT_vsync              ),
    .TFT_data               (rgb                    )   
);
//==========================================================================
//==                        添加視頻水印
//==========================================================================
mark_rom u_mark_rom
(
    .clock                  (clk_10m                ),
    .address                (rom_addr               ),
    .q                      (rom_data               )
);
//--------------------------------------------------------------------------
//水印范圍
assign rom_rden = (TFT_x >= 1) && (TFT_x <=50) && 
                  (TFT_y >= 1) && (TFT_y <=50);

//rom地址
always @(posedge clk_10m or negedge rst_n) begin
    if(!rst_n)
        rom_addr <= 12'b0;
    else if(rom_addr==2500-1)
        rom_addr <= 12'b0;
    else if(rom_rden)
        rom_addr <= rom_addr + 1'b1;
end

//數據顯示 
always @(*) begin
    if(rom_rden) begin
        TFT_data <= rom_data;      //顯示水印
    end
    else
        TFT_data <= rgb;               //顯示原圖
end

   其中 rgb 是原本輸出到管腳上的,拿來到“添加視頻水印”模塊做進一步的處理,而 TFT_x、TFT_y 信號是 TFT_driver 里就設計好的坐標信號,這里不得不又說一下,模塊設計的好,移植性就非常強!

  如果你的 TFT 或 VGA 驅動模塊沒有設計坐標信號,那么在后面用 de 使能信號設計一下就行,其實就是行列規划的計數器而已。

  OK來看看下效果:

  設計成功!我的FPGA開發板引腳有問題,那些紅點並不是本工程的 bug 。
 
2、半透明水印
  上面添加的水印比較生硬,可不可以美化一下呢?是可以的,我們可以讓其變得半透明,並且會隨着圖像的變換跟着變換,仿佛是融入了圖像內部一樣。
  代碼如下所示:
always @(*) begin
    if(rom_rden) begin
        TFT_data <= rom_data + rgb;   //顯示水印
    end
    else
        TFT_data <= rgb;              //顯示原圖
end

   將 rom_data 和 rgb 數據相加,最后實現的效果如下所示:

  ......好像有點打臉?
  是打臉,也不是打臉,怎么說呢?因此我的水印圖案是彩色繽紛的,和原本像素值相加后效果不好,白色的略去了,但是其他色彩也變形了。但是如果我們把水印圖案的主要符號選擇為黑色,效果就會非常好,感興趣的同學可以試試。
 
3、略去背景的水印圖案
  如果不喜歡上面第2種效果,那我們再改進一下吧,水印圖案的輸出就不進行和原像素相加了。觀察一下我的水印圖案,背景是白色的,因此我們可以想辦法把白色背景略去,只保留中心的圖案。代碼如下所示:
always @(*) begin
    if(rom_rden) begin
        if(rom_data==16'hffff)              //背景白色顯示原圖
            TFT_data <= rgb;
        else
            TFT_data <= rom_data;// + rgb;  //否則顯示水印
    end
    else
        TFT_data <= rgb;                    //顯示原圖
end

   對水印圖案進行判斷,如果是白色,則顯示原圖,否則顯示水印,非水印區域也顯示原圖。最后效果如下所示:

  效果還是不錯的,水印圖案還是沒有選的特別好,頭發那有些白點沒有略去,那的像素並不是肉眼以為的純白,而是一些像白色的灰度數據。如果要達到最好的效果,可以好好對水印圖案進行一番選擇。
  實驗整體效果如下所示:
  從視頻上可以看到,最后的效果還是不錯的,可惜我的板卡有問題,很多地方有紅點,而且顏色有些失真了,此外 OV7670 攝像頭的成像效果本身也不行。不過我們關注水印就夠了,本次FPGA實現視頻圖像的水印添加實驗宣告成功!
 
后記
  熟悉rom的同學會發現本工程的代碼時序應該再調整一下,因為ROM給出地址到出數據是有一定延遲的。但是本工程只是為了看看水印效果,要時序完美對齊也很簡單,但代碼量明顯增多,de,vsync,hsync等都得拿出來打拍。而且現在這樣效果挺完美,就這樣吧。
 
 
參考資料:[1]OpenS Lee:FPGA開源工作室(公眾號)
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM