请选择 进入手机版 | 继续访问电脑版

risc-v中文社区

 找回密码
 立即注册
查看: 2034|回复: 4

[原创] 用SpinalHdl将RGB图像转换为GRAY图像

  [复制链接]

2

主题

5

帖子

50

积分

版主

Rank: 7Rank: 7Rank: 7

积分
50
发表于 2021-8-18 15:21:33 | 显示全部楼层 |阅读模式
import spinal.core._

class img2gray extends Component {
    val io = new Bundle {
        val r = in UInt (8 bits)
        val g = in UInt (8 bits)
        val b = in UInt (8 bits)
        val data_in_valid = in Bool()
        val gray = out UInt (8 bits)
        val data_out_valid = out Bool()
    }
    noIoPrefix()
    def rgb2gray(value: UInt, p: Float): UInt = (value * U((255 * p).toInt, 8 bits)) >> 8

    val r_temp = RegNext(rgb2gray(io.r,0.299f))
    val g_temp = RegNext(rgb2gray(io.g,0.587f))
    val b_temp = RegNext(rgb2gray(io.b,0.114f))
    io.gray := RegNext(r_temp+g_temp+b_temp)
    io.data_out_valid := RegNext(RegNext(io.data_in_valid))
}

object img2gray{
    def main(args: Array[String]): Unit = {
        SpinalVerilog(new img2gray)
    }
}
回复

使用道具 举报

2

主题

5

帖子

50

积分

版主

Rank: 7Rank: 7Rank: 7

积分
50
 楼主| 发表于 2021-8-18 15:22:30 | 显示全部楼层
生成的Verilog代码:
// Generator : SpinalHDL v1.6.0    git head : 73c8d8e2b86b45646e9d0b2e729291f2b65e6be3
// Component : img2gray



module img2gray (
  input      [7:0]    r,
  input      [7:0]    g,
  input      [7:0]    b,
  input               data_in_valid,
  output     [7:0]    gray,
  output              data_out_valid,
  input               clk,
  input               reset
);
  wire       [15:0]   _zz_r_temp;
  wire       [15:0]   _zz_g_temp;
  wire       [15:0]   _zz_b_temp;
  wire       [7:0]    _zz__zz_gray;
  reg        [7:0]    r_temp;
  reg        [7:0]    g_temp;
  reg        [7:0]    b_temp;
  reg        [7:0]    _zz_gray;
  reg                 data_in_valid_regNext;
  reg                 data_in_valid_regNext_regNext;

  assign _zz_r_temp = (r * 8'h4c);
  assign _zz_g_temp = (g * 8'h95);
  assign _zz_b_temp = (b * 8'h1d);
  assign _zz__zz_gray = (r_temp + g_temp);
  assign gray = _zz_gray;
  assign data_out_valid = data_in_valid_regNext_regNext;
  always @(posedge clk) begin
    r_temp <= (_zz_r_temp >>> 8);
    g_temp <= (_zz_g_temp >>> 8);
    b_temp <= (_zz_b_temp >>> 8);
    _zz_gray <= (_zz__zz_gray + b_temp);
    data_in_valid_regNext <= data_in_valid;
    data_in_valid_regNext_regNext <= data_in_valid_regNext;
  end


endmodule
回复

使用道具 举报

2

主题

5

帖子

50

积分

版主

Rank: 7Rank: 7Rank: 7

积分
50
 楼主| 发表于 2021-8-18 15:24:18 | 显示全部楼层
使用Spinal Hdl进行仿真
import spinal.core.sim._
import spinal.core._

import java.awt.Color

import java.io.{ File , PrintWriter}
import javax.imageio.ImageIO
object tb_img2gray {
    def main(args: Array[String]): Unit = {
        val sourceImage = new File("sim/RGB2GRAY/source.jpg")   //读取的原图片
        val image = ImageIO.read(sourceImage)
        val w = image.getWidth()
        val h = image.getHeight()
        val testB_data_in_path = "sim/RGB2GRAY/testB_data_in_path.txt"
        val testB_data_out_path = "sim/RGB2GRAY/testB_data_out_path.txt"        //将结果保存为txt
        val fi_d = new PrintWriter(testB_data_in_path)
        val fo_d = new PrintWriter(testB_data_out_path)
        SimConfig
            .withWave
            .workspacePath("sim/RGB2GRAY")
            .withConfig(SpinalConfig(
                defaultClockDomainFrequency = FixedFrequency(100 MHz),
                defaultConfigForClockDomains = ClockDomainConfig(resetKind = ASYNC)
            ))
            .compile(new img2gray())
            .doSim("testB") { dut =>
                dut.clockDomain.forkStimulus(10)
                dut.io.data_in_valid #= false
                dut.io.r #= 0
                dut.io.g #= 0
                dut.io.b #= 0
                dut.clockDomain.waitSampling(10)

                for(i <- 0 until w)
                    for(j <- 0 until(h)){
                        val rgb = new Color(image.getRGB(i,j))
                        dut.io.r #= rgb.getRed
                        dut.io.g #= rgb.getGreen
                        dut.io.b #= rgb.getBlue
                        dut.io.data_in_valid #= true
                        dut.clockDomain.waitSampling(1)
                        fi_d.write(rgb.getRed + " " + rgb.getGreen + " " + rgb.getBlue + "\n")
                        if (dut.io.data_out_valid.toBoolean) {
                            fo_d.write(dut.io.gray.toInt + "\n")
                        }
                    }
                fi_d.close()
                dut.io.data_in_valid #= false
                dut.clockDomain.waitSampling(1)
                while (dut.io.data_out_valid.toBoolean){
                    fo_d.write(dut.io.gray.toInt + "\n")
                    dut.clockDomain.waitSampling(1)
                }
                fo_d.close()

            }

    }

}
回复

使用道具 举报

2

主题

5

帖子

50

积分

版主

Rank: 7Rank: 7Rank: 7

积分
50
 楼主| 发表于 2021-8-18 15:35:03 | 显示全部楼层
因为上面的代码是将仿真后的结果保存到txt文件了,如果不能通过可视化的方式显示结果就太可惜了。
下面是一段python代码通过提取这个txt文件中的值来生成jpg格式的图片。
from PIL import Image
import math

file = open(r'F:\test\sim\RGB2GRAY\testB_data_out_path.txt')
img = Image.open(r"F:\test\sim\RGB2GRAY\source.jpg")
x = img.width
y = img.height
im = Image.new("RGB", (x, y))

for i in range(0, x):
    for j in range(0, y):
        line = file.readline()
        rgb = line.split(" ")
        im.putpixel((i, j), (int(rgb[0]), int(rgb[0]), int(rgb[0])))

im.save(r"F:\test\sim\RGB2GRAY\dest.jpg")


下面是仿真用的原图和生成的结果图。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-8-18 17:16:16 | 显示全部楼层
好象SpinalHDL比chisel有更好的官方参考文档,抽空研究研究,好帖。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-3-29 20:34 , Processed in 0.017945 second(s), 18 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表