在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何在FPGA中實現RGB轉HSV

FPGA開源工坊 ? 來源:FPGA開源工坊 ? 2023-07-02 11:49 ? 次閱讀

HSV色彩空間相對于RGB色彩空間更適合做顏色追蹤,分割顏色等。那么RGB色彩空間要怎么轉變為HSV色彩空間呢。

轉換公式如下:

7a9fcc5a-1825-11ee-962d-dac502259ad0.png

需要注意的是在OpenCV中為了顯示HSV色彩空間的內容會將H的值除以2,S的值和V的值是要乘以255。

FPGA中實現RGB轉HSV的話,上面公式中第一步除以255的歸一化是可以不做的。因為在H和S的計算中255可以約掉的,如下所示。而在V的值需要乘以255來顯示,所以也可以不除以255.

7ad93fda-1825-11ee-962d-dac502259ad0.png

如R,G,B為169 152 133的值計算過程如下:

7af3848a-1825-11ee-962d-dac502259ad0.png

定義如下

7b0e3816-1825-11ee-962d-dac502259ad0.png

在計算中需要使用除法器:

7b30036a-1825-11ee-962d-dac502259ad0.png

因為8bit的整數,8bit小數的有符號數,所以數據位寬為17bit。

仿真結果如下:

7b462d48-1825-11ee-962d-dac502259ad0.png

可以看到ref和dut之間有誤差,這個是因為計算過程中采用了8bit的定點小數造成的,如果小數位寬擴大,那么可以減少誤差。

仿真用的計分板:

7b670a68-1825-11ee-962d-dac502259ad0.png

提供SpinalHDL的源碼:如果需要Verilog源碼可以私聊

import spinal.core._
import spinal.lib._


class Rgb2hsv extends Component {
    val io = new Bundle {
        val dataIn = slave(FrameInterface(24))
        val dataOut = master(FrameInterface(24))
    }


    val R, G, B = UInt(8 bits)
    val RMax = Reg(Bool()) init False
    val GMax = Reg(Bool()) init False
    val BMax = Reg(Bool()) init False
    val RMaxDelay = Delay(RMax, 12, init = False)
    val GMaxDelay = Delay(GMax, 12, init = False)
    val BMaxDelay = Delay(BMax, 12, init = False)
    val CMax = Reg(UInt(8 bits))
    val CMin = Reg(UInt(8 bits))
    val derta = UInt(8 bits)


    val calcH = new Area {
        val dertaEq0 = Delay(derta === 0, 12)
        val G_B = RegNext(((U"1'b0" @@ G).asSInt - (U"1'b0" @@ B).asSInt) @@ S"8'd0")
        val B_R = RegNext(((U"1'b0" @@ B).asSInt - (U"1'b0" @@ R).asSInt) @@ S"8'd0")
        val R_G = RegNext(((U"1'b0" @@ R).asSInt - (U"1'b0" @@ G).asSInt) @@ S"8'd0")
        val div1 = new Div(17, 8)
        val div2 = new Div(17, 8)
        val div3 = new Div(17, 8)
        val G_B_derta = Bits(17 bits)
        val B_R_derta = Bits(17 bits)
        val R_G_derta = Bits(17 bits)
        val G_B_derta_add = Reg(SInt(17 bits))
        val B_R_derta_add = Reg(SInt(17 bits))
        val R_G_derta_add = Reg(SInt(17 bits))
        val G_B_derta_add_mul = Reg(SInt(16 bits))
        val B_R_derta_add_mul = Reg(SInt(16 bits))
        val R_G_derta_add_mul = Reg(SInt(16 bits))
        val H_D = Reg(UInt(9 bits))
        val H = Reg(UInt(8 bits))
        div1.driverFrom(G_B.asBits, (U"1'b0" @@ derta @@ U"8'b0").asBits, RMax, G_B_derta)
        div2.driverFrom(B_R.asBits, (U"1'b0" @@ derta @@ U"8'b0").asBits, GMax, B_R_derta)
        div3.driverFrom(R_G.asBits, (U"1'b0" @@ derta @@ U"8'b0").asBits, BMax, R_G_derta)


        G_B_derta_add := G_B_derta.asSInt
        B_R_derta_add := B_R_derta.asSInt + 2 @@ S"8'b0"
        R_G_derta_add := R_G_derta.asSInt + 4 @@ S"8'b0"


        val mul60 = AFix.S(8 exp, -8 exp)
        val afixG_B_derta_add = AFix.S(8 exp, -8 exp)
        val afixB_R_derta_add = AFix.S(8 exp, -8 exp)
        val afixR_G_derta_add = AFix.S(8 exp, -8 exp)
        afixG_B_derta_add := G_B_derta_add
        afixB_R_derta_add := B_R_derta_add
        afixR_G_derta_add := R_G_derta_add
        mul60 := S"9'd60" @@ S"8'd0"
        G_B_derta_add_mul := (mul60 * afixG_B_derta_add).roundHalfUp(0).asSInt().resized
        B_R_derta_add_mul := (mul60 * afixB_R_derta_add).roundHalfUp(0).asSInt().resized
        R_G_derta_add_mul := (mul60 * afixR_G_derta_add).roundHalfUp(0).asSInt().resized


        //  val H = SInt(9 bits)
        (R, G, B) := io.dataIn.data
        when(R >= G && R >= B) {
            CMax := R
            RMax := True
            GMax := False
            BMax := False
        } elsewhen (G >= R && G >= B) {
            CMax := G
            RMax := False
            GMax := True
            BMax := False
        } otherwise {
            CMax := B
            RMax := False
            GMax := False
            BMax := True
        }


        when(R <= G && R <= B) {
            CMin := R
        } elsewhen (G <= R && G <= B) {
            CMin := G
        } otherwise {
            CMin := B
        }
        derta := CMax - CMin


        when(dertaEq0) {
            H_D := 0
        } elsewhen (RMaxDelay) {
            when(G_B_derta_add_mul.sign) {
                H_D := (G_B_derta_add_mul +^ 360).asUInt.resized
            } otherwise {
                H_D := G_B_derta_add_mul(8 downto 0).asUInt.resized
            }


        } elsewhen (GMaxDelay) {
            when(B_R_derta_add_mul.sign) {
                H_D := (B_R_derta_add_mul + 360).asUInt.resized
            } otherwise {
                H_D := B_R_derta_add_mul(8 downto 0).asUInt.resized
            }
        } elsewhen (BMaxDelay) {
            when(R_G_derta_add_mul.sign) {
                H_D := (R_G_derta_add_mul + 360).asUInt.resized
            } otherwise {
                H_D := R_G_derta_add_mul(8 downto 0).asUInt.resized
            }
        }
        H := (H_D(8 downto 1) + H_D(0).asUInt)


    }


    val calcS = new Area {
        val S_Div = Bits(17 bits)
        val div = new Div(17, 8)
        div.driverFrom((U"1'd0" @@ derta @@ U"8'd0").asBits, (U"1'd0" @@ CMax @@ U"8'd0").asBits, RegNext(io.dataIn.valid), S_Div)
        val mul255 = AFix.S(8 exp, -8 exp)
        val afixS = AFix.S(8 exp, -8 exp)
        afixS := S_Div.asSInt
        mul255 := S"9'd255" @@ S"8'd0"
        val afix_mul = RegNext(afixS * mul255)
        val afix_mul_r = RegNext(RegNext(afix_mul.roundHalfUp(0)).asUInt())
        val S = Reg(UInt(8 bits))
        val CMaxEq0 = Delay(CMax === 0, 13)
        when(CMaxEq0){
            S := 0
        } otherwise{
            S := afix_mul_r(7 downto 0)
        }
    }


    val calcV = new Area {
        val V = Delay(CMax, 14)
    }


    io.dataOut.valid := Delay(io.dataIn.valid, 15, init = False)
    io.dataOut.data := (calcH.H @@ calcS.S @@ calcV.V).asBits


}


object Rgb2hsv extends App {
    SpinalVerilog(new Rgb2hsv)
}

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1630

    文章

    21798

    瀏覽量

    606022
  • 圖像處理
    +關注

    關注

    27

    文章

    1300

    瀏覽量

    56894
  • RGB
    RGB
    +關注

    關注

    4

    文章

    801

    瀏覽量

    58716
  • HSV
    HSV
    +關注

    關注

    0

    文章

    10

    瀏覽量

    2615

原文標題:FPGA圖像處理--RGB轉HSV

文章出處:【微信號:FPGA開源工坊,微信公眾號:FPGA開源工坊】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    FPGA工程師:如何在FPGA實現狀態機?

    安全高效的狀態機設計對于任何使用FPGA的工程師而言都是一項重要技能。選擇Moore狀態機、Mealy狀態機還是混合機取決于整個系統的需求。無論選擇哪種類型的狀態機,充分掌握實現方案所需的工具和技巧,將確保您實現最佳解決方案。本
    發表于 03-29 15:02 ?1.3w次閱讀
    <b class='flag-5'>FPGA</b>工程師:如<b class='flag-5'>何在</b><b class='flag-5'>FPGA</b><b class='flag-5'>中</b><b class='flag-5'>實現</b>狀態機?

    何在FPGA實現過零檢測器?

    大家好!我想知道如何在FPGA中使用VHDL實現過零檢測器。所以我想實現一個數字常數小數鑒別器。 firt部分提供了雙極性信號,但我想知道如何在
    發表于 01-29 08:16

    什么是CVSD?其算法分析如何在FPGA實現

    的不足,同時也方便在現場可編程門陣列(FPGA)增加一些其他相關的應用功能,因此在FPGA實現CVSD語音編譯碼調制功能的前景將是非常廣
    發表于 08-07 07:04

    何在FPGA實現實時時鐘或時間和日期計數器

    嗨,我是Xilinx FPGA的新手。我該如何在FPGA實現實時時鐘或時間和日期計數器?Xilinx是否為Artix 7提供任何RTC核心
    發表于 05-22 12:41

    何在Virtex-7 FPGA實現動態部分配置

    嗨,如何在Virtex-7 FPGA實現動態部分配置?問候,Suresh Palani
    發表于 05-29 11:30

    何在低端FPGA實現DPA的功能?

    FPGA,動態相位調整(DPA)主要是實現LVDS接口接收時對時鐘和數據通道的相位補償,以達到正確接收的目的。那么該如何在低端FPGA
    發表于 04-08 06:47

    請問在FPGA上怎么實現RGB轉換到YCbCr?

    本文推導出一種適合在FPGA實現RGB到YCbCr。顏色空間變換的新算法,采用單片FPGA完成電路設計,利用FPGA內嵌DSP核
    發表于 04-29 06:57

    低成本FPGA實現動態相位調整方案

    FPGA,動態相位調整(DPA)主要是實現LVDS接口接收時對時鐘和數據通道的相位補償,以達到正確接收的目的。ALTERA的高端FPGA,如STRATIX(r) 系列
    的頭像 發表于 02-16 17:32 ?1.1w次閱讀
    低成本<b class='flag-5'>FPGA</b><b class='flag-5'>中</b><b class='flag-5'>實現</b>動態相位調整方案

    萊迪思FPGA助力玩視科技(HDCVT)實現SDIHDMI解決方案

    近日宣布深圳玩視科技有限公司(HDCVT)采用萊迪思FPGA器件提供的豐富高速SERDES資源和靈活的I/O接口,實現雙通道3G SDIHDMI/VGA/RGB橋接。
    發表于 01-04 12:00 ?1889次閱讀

    淺析基于labview的RGBHSV轉換

    在labview的應用環境,通過C語言的方式實現RGBHSV的轉換。
    發表于 11-15 16:47 ?19次下載

    ICN6211-6202MIPIRGB MIPILVDS

    集創北方,ICN6211-ICN6202 MIPIRGB,MIPILVDS,芯片在MTK,高通,全志,RK方案商已經調試運用量產 ?
    的頭像 發表于 06-24 15:15 ?3673次閱讀
    ICN6211-6202MIPI<b class='flag-5'>轉</b><b class='flag-5'>RGB</b> MIPI<b class='flag-5'>轉</b>LVDS

    RGBHDMI開源項目

    電子發燒友網站提供《RGBHDMI開源項目.zip》資料免費下載
    發表于 07-21 10:29 ?14次下載
    <b class='flag-5'>RGB</b><b class='flag-5'>轉</b>HDMI開源項目

    如何利用OpenCV進行顏色分類 rgbhsv的區別

    如果光源不穩定,光照變化較大(存在陰影或者亮斑),則利用HSV通道檢測就比RGB檢測高效得多。光照變化較大時,對RGB三個色道的參數影響都很大,在實際調參過程中會顯得非常麻煩,而且效果不理想。
    發表于 08-07 09:52 ?1509次閱讀
    如何利用OpenCV進行顏色分類 <b class='flag-5'>rgb</b>和<b class='flag-5'>hsv</b>的區別

    何在FPGA實現狀態機

    FPGA(現場可編程門陣列)實現狀態機是一種常見的做法,用于控制復雜的數字系統行為。狀態機能夠根據當前的輸入和系統狀態,決定下一步的動作和新的狀態。這里,我們將詳細探討如何在
    的頭像 發表于 07-18 15:57 ?729次閱讀

    何在FPGA實現隨機數發生器

    分享如何在Xilinx Breadboardable Spartan-7 FPGA, CMOD S7實現4位偽隨機數發生器(PRNGs)。
    的頭像 發表于 08-06 11:20 ?772次閱讀
    如<b class='flag-5'>何在</b><b class='flag-5'>FPGA</b><b class='flag-5'>中</b><b class='flag-5'>實現</b>隨機數發生器
    主站蜘蛛池模板: 亚洲 午夜在线一区 | 久久久久久综合 | 国产偷啪视频一区 | 国产精品色婷婷在线观看 | 激情五月婷婷综合网 | 四虎影视在线影院4hutv | 国产免费卡1卡2卡 | 每日最新avhd101天天看新片 | 欧美精品激情 | 午夜影视免费完整高清在线观看网站 | 午夜一级在线 | 国产特黄1级毛片 | 在线视频精品免费 | 国产伦精品一区二区三区女 | free性欧美video | 国产视频一二区 | 国产免费成人在线视频 | 热re66久久精品国产99热 | 精品视频日本 | 久久青草免费免费91线频观看 | 色五月情| 精品国产成人三级在线观看 | 国产一区二区三区乱码 | 亚洲一本之道在线观看不卡 | 免费免费啪视频在线 | 久久精品国产精品亚洲红杏 | 久久精品国产福利国产琪琪 | 真实国产伦子系 | 激情三级视频 | 一级毛片免费在线观看网站 | 婷婷网五月天天综合天天爱 | 天天摸天天爽天天澡视频 | 91最新网站免费 | 免费在线一区二区三区 | 日本国产高清色www视频在线 | 国产美女在线精品免费观看 | 你懂得的在线观看免费视频 | 国产成人精品高清免费 | 亚洲视频1 | 亚洲午夜免费视频 | 国产成在线人视频免费视频 |