图像预处理算法————灰度化处理

这篇具有很好参考价值的文章主要介绍了图像预处理算法————灰度化处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

图像预处理算法适合在FPGA上完成,原理简单且需要快速处理,通常有灰度化、中值、均值滤波等,以及颜色空间转换算法。

灰度图像是一种特殊的彩色图像(R=G=B的彩色图像) 只有一种颜色分量,单通道的0-255

方法:一般有分量法、最大值法、平均值法、加权平均法四种方法对彩色图像进行灰度化。

一:最大值法

将彩色图像中的三分量亮度 R G B 的最大值作为灰度图的灰度值。具体表达式如下。
                                           
                                             gray(i, j) = max[𝑅(𝑖,𝑗),𝐺(𝑖,𝑗),𝐵(𝑖,𝑗)]

二:平均值法

1.原理

将彩色图像中的三分量亮度求平均得到一个灰度值。如下
                             gray(i, j) = { 𝑅(𝑖,𝑗) + 𝐺(𝑖,𝑗) + 𝐵(𝑖,𝑗) }  / 3
上式中有除法,考虑到在 FPGA 中实现除法比较的消耗资源(除法就可以使用 移位的方式 实现),这里在实现前可以先做如下的近似处理:
灰度化平均加权法实现流程,fpga开发

 除以256可以看作是向右移8位,同样,512,1024,2048等2的n次都可以

2.verilog实现

分析:只有加法乘法以及移位操作

module rgb2gray

(
  input           clk,         //时钟
  input           reset_p,     //复位
  input           rgb_valid,   //rgb输入有效标识
  input           rgb_hs,      //rgb输入行信号
  input           rgb_vs,      //rgb输入场信号
  input     [7:0] red_8b_i,    //R输入
  input     [7:0] green_8b_i,  //G输入
  input     [7:0] blue_8b_i,   //B输入

  output    [7:0] gray_8b_o,   //GRAY输出
  output reg      gray_valid,  //gray输出有效标识
  output reg      gray_hs,     //gray输出行信号
  output reg      gray_vs      //gray输出场信号
);

//求平均法GRAY = (R+B+G)/3=((R+B+G)*85)>>8 =((R+B+G)*(64+16+4+1))>>8

=(R+B+G)*64+(R+B+G)*16+(R+B+G)*4+(R+B+G) >>8

= (sum << 6)+(sum << 4)+(sum << 2)+ sum >>8

  wire [9:0]sum;
  reg [15:0]gray_r;

 assign sum = red_8b_i + green_8b_i + blue_8b_i;
 
 always@(posedge clk or posedge reset_p)
 begin
 if(reset_p)
 gray_r <= 16'd0;
 else if(rgb_valid)
 gray_r <= (sum << 6)+(sum << 4)+(sum << 2)+ sum;
 else
 gray_r <= 16'd0;
 end
 assign gray_8b_o = gray_r[15:8];   //>>8右移8位

 always@(posedge clk)
 begin
 gray_valid <= rgb_valid;
 gray_hs <= rgb_hs;
 gray_vs <= rgb_vs;
 end
避免除法做近似处理计算的 gray 和 直接通过除法求的平均值  是稍存在偏差的。这个是可以接收的误差范围。

三,加权平均 RGB--Ycbcr

1.基本原理

Y'为颜色的亮度(luma)分量、而CB和CR则为蓝色和红色的浓度偏移量成份。常见的3 个基本色彩模型是RGB,CMYK和YUV。YCbCr是YUV经过缩放和偏移的翻版,JPEG、MPEG均采用此格式。主要的子采样格式有 YCbCr 4:2:0、YCbCr 4:2:2 和 YCbCr 4:4:4。

RGB888 转 YCbCr 的公式,
灰度化平均加权法实现流程,fpga开发
效果如下:
灰度化平均加权法实现流程,fpga开发

图来自:FPGA实现图像灰度转换(2):RGB转YCbCr转Gray - 咸鱼IC - 博客园 (cnblogs.com)

将三个分量以不同的权值进行加权平均:

gray(i, j) = 0.299 ∗ 𝑅(𝑖,𝑗) + 0.587 ∗ 𝐺(𝑖,𝑗) + 0.114 ∗ 𝐵(𝑖,𝑗)

在实际应用时,为了能避免低速的浮点运算以及除法运算,先将式子缩放 1024 倍来实现运算算法,如下:

gray(i, j) = [0.299 ∗ 𝑅(𝑖,𝑗) + 0.587 ∗ 𝐺(𝑖,𝑗) + 0.114 ∗ 𝐵(𝑖,𝑗)] ∗ 1024/1024
近似取整处理后:
gray(i, j) ≈ [306 ∗ 𝑅(𝑖,𝑗) + 601 ∗ 𝐺(𝑖,𝑗) + 117 ∗ 𝐵(𝑖,𝑗)]/1024

除以1024使用向右移10位:

gray(i, j) ≈ [306 ∗ 𝑅(𝑖,𝑗) + 601 ∗ 𝐺(𝑖,𝑗) + 117 ∗ 𝐵(𝑖,𝑗)] ≫ 10
也可以压缩到 8 位以内,式子变为如下。具体压缩到多少位可以根据实际需求:
gray(i, j) = [77 ∗ 𝑅(𝑖,𝑗) + 150 ∗ 𝐺(𝑖,𝑗) + 29 ∗ 𝐵(𝑖,𝑗)] ≫ 8

2.代码实现

1)公式计算法实现:

首先将RGB565转RGB888形式:

 rgb2gray
  #(
    .PROC_METHOD ( "FORMULA" )//"AVERAGE"     :求平均法
                              //or "FORMULA"  :直接公式法
                              //or "LUT"      :查找表法
  )rgb2gray
  (
    .clk        (loc_clk50m                ),//input
    .reset_p    (g_rst_p                   ),//input
    .rgb_valid  (image_data_valid          ),//input
    .rgb_hs     (image_data_hs             ),//input
    .rgb_vs     (image_data_vs             ),//input

    .red_8b_i   ({image_data[15:11],3'b000}),//input     R[7:0]
    .green_8b_i ({image_data[10:5],2'b00}  ),//input     G[7:0]
    .blue_8b_i  ({image_data[4:0],3'b000}  ),//input     B[7:0]

    .gray_8b_o  (image_gray_data           ),//output    [7:0]
    .gray_valid (image_gray_data_valid     ),//output reg
    .gray_hs    (                          ),//output reg
    .gray_vs    (                          ) //output reg
  );
    wire [15:0]red_x77;
    wire [15:0]green_x150;
    wire [15:0]blue_x29;
    reg  [15:0]sum;

    //乘法转换成移位相加方式
    assign red_x77    = (red_8b_i  << 6) + (red_8b_i  << 3) + (red_8b_i  << 2) + red_8b_i;
    assign green_x150 = (green_8b_i<< 7) + (green_8b_i<< 4) + (green_8b_i<< 2) + (green_8b_i<<1);
    assign blue_x29   = (blue_8b_i << 4) + (blue_8b_i << 3) + (blue_8b_i << 2) + blue_8b_i;

    always@(posedge clk or posedge reset_p)
    begin
      if(reset_p)
        sum <= 16'd0;
      else if(rgb_valid)
        sum <= red_x77 + green_x150 + blue_x29;
      else
        sum <= 16'd0;
    end

//提取Y亮度为灰度输出
    assign gray_8b_o = sum[15:8];

//打拍计算
    always@(posedge clk)
    begin
      gray_valid <= rgb_valid;
      gray_hs    <= rgb_hs;
      gray_vs    <= rgb_vs;
    end
进行打拍计算,在图像处理时,我们是有数据的同步信号的,有的是数据使能信号,有的还有行同步信号和帧同步信号。经过图像处理后的数据延迟了拍数,这些同步信号也要相应的打拍,否则最终的图像显示会出问题。
Y,Cb,Cr分量都获取的代码实现办法:
module rgb2gray
(
  input           clk,         //时钟
  input           reset_p,     //复位

  input           rgb_valid,   //rgb输入有效标识
  input           rgb_hs,      //rgb输入行信号
  input           rgb_vs,      //rgb输入场信号
  input     [7:0] red_8b_i,    //R输入
  input     [7:0] green_8b_i,  //G输入
  input     [7:0] blue_8b_i,   //B输入

  output reg   [7:0] gray_8b_o,   //GRAY输出
  output       gray_valid,  //gray输出有效标识
  output       gray_hs,     //gray输出行信号
  output       gray_vs      //gray输出场信号
);
//典型灰度转换公式Gray = R*0.299+G*0.587+B*0.114=(R*77 + G*150 + B*29) >>8
//        Y   =   0.299*R + 0.587*G + 0.114*B
//        Cb  =   0.586*(B-Y) + 128 = -0.172*R - 0.339*G + 0.511*B + 128
//        Cr  =   0.713*(R-Y) + 128 =  0.511*R - 0.428*G - 0.083*B + 128
// --->
//        Y   =   ( 77*R  +  150*G  +   29*B) >> 8
//        Cb  =   (-43*R  -   85*G  +  128*B) >> 8 + 128
//        Cr  =   (128*R  -  107*G  -   21*B) >> 8 + 128
// --->
//        Y   =   ( 77*R  +  150*G  +   29*B) >> 8
//        Cb  =   (-43*R  -   85*G  +  128*B + 32768) >> 8
//        Cr  =   (128*R  -  107*G  -   21*B + 32768) >> 8
    reg  [15:0] R1;
    reg  [15:0] R2;
    reg  [15:0] R3;
    reg  [15:0] G1;
    reg  [15:0] G2;
    reg  [15:0] G3;
    reg  [15:0] B1;
    reg  [15:0] B2;
    reg  [15:0] B3;
    reg  [15:0] Y1;
    reg  [15:0] Cb1;
    reg  [15:0] Cr1;
    reg  [7:0] Y2,Cb2,Cr2;
    reg  [3:0]   rgb_valid_r;   //rgb输入有效标识
    reg  [3:0]   rgb_hs_r;     //rgb输入行信号
    reg  [3:0]   rgb_vs_r;     //rgb输入场信号
提取三种分量的RGB值,并且进行相加得到
    always@(posedge clk or negedge reset_p) begin
      if (reset_p) begin
          {R1,G1,B1} <= {16'd0,16'd0,16'd0};
          {R2,G2,B2} <= {16'd0,16'd0,16'd0};
          {R3,G3,B3} <= {16'd0,16'd0,16'd0};
      end
      else begin
          {R1,G1,B1} <= {{red_8b_i * 16'd77},{green_8b_i * 16'd150},{blue_8b_i * 16'd29}};
          {R2,G2,B2} <= {{red_8b_i * 16'd43},{green_8b_i * 16'd85},{blue_8b_i * 16'd128}};
          {R3,G3,B3} <= {{red_8b_i * 16'd128},{green_8b_i * 16'd107},{blue_8b_i * 16'd21}};
      end
    end

    always@(posedge clk or negedge reset_p) begin
      if (reset_p) begin
          Y1  <= 16'd0;
          Cb1 <= 16'd0;
          Cr1 <= 16'd0;
      end
      else begin
          Y1  <= R1+G1+B1;
          Cb1 <= B2 - R2 - G2 + 16'd32768;//128扩大256倍
          Cr1 <= R3 - G3 - B3 + 16'd32768; //128扩大256倍
      end
    end

//右移8位得到
    always@(posedge clk or negedge reset_p) begin
      if (reset_p) begin
        Y2  <= 8'd0;
        Cb2 <= 8'd0;
        Cr2 <= 8'd0;
      end
      else begin
        Y2  <= Y1[15:8];  
        Cb2 <= Cb1[15:8];
        Cr2 <= Cr1[15:8];
    end
  end

最终输出Y分量为灰度:
assign gray_8b_o = Y2;
在HDMI显示屏上进行显示灰度处理实现的效果:

灰度化平均加权法实现流程,fpga开发

也可以只提取77 < Cb < 127,133 < Cr < 173输出值为8'hFF,也就是说将该范围内的图像标记出来。即肤色提取:

    always@(posedge clk or negedge reset_p) begin
      if (reset_p) 
         gray_8b_o <= 8'h0;
      else if ( (Cb2 > 77) && (Cb2 < 127) && (Cr2 > 133) && (Cr2 < 173))
         gray_8b_o <= 8'hFF;
      else
        gray_8b_o <= 8'h0;
      end
在HDMI显示屏上进行显示肤色提取实现的效果:

灰度化平均加权法实现流程,fpga开发

 可以发现,它的椒盐噪声太多,需要进行滤波处理来减少椒盐噪声。

2)查找表法:
采用查找表方法实现,主要的优势是直接通过 访问 ROM 内的数据,相对使用移位相加实现乘法使用的 LUT 资源会少点,但占用的存储器会更多。
需要将 R G B 乘以系数之后的数值存储在 ROM 中,然后通过读取 ROM 方式来得到计算之后的数值。使用 Vivado 添加 3 个 ROM IP 核,分别通过 R*75、G*147、B*36(0≤R≤255,0≤G≤255,0≤B≤255)的计算值建立 3 个初始化 coe 文件.
    rom_red_x77 rom_red_x77(
      .clka  (clk       ), // input wire clka
      .ena   (rgb_valid ), // input wire ena
      .addra (red_8b_i  ), // input wire [7 : 0] addra
      .douta (red_x77   )  // output wire [14 : 0] douta
    );
    
    rom_green_x150 rom_green_x150(
      .clka  (clk        ), // input wire clka
      .ena   (rgb_valid  ), // input wire ena
      .addra (green_8b_i ), // input wire [7 : 0] addra
      .douta (green_x150 )  // output wire [15 : 0] douta
    );
  
    rom_blue_x29 rom_blue_x29(
      .clka  (clk        ), // input wire clka
      .ena   (rgb_valid  ), // input wire ena
      .addra (blue_8b_i  ), // input wire [7 : 0] addra
      .douta (blue_x29   )  // output wire [13 : 0] douta
    );
    always@(posedge clk or posedge reset_p)
    begin
      if(reset_p)
        sum <= 16'd0;
      else if(rgb_valid_dly1)
        sum <= red_x77 + green_x150 + blue_x29;
      else
        sum <= 16'd0;
    end

    assign gray_8b_o = sum[15:8];
    always@(posedge clk)
    begin
      rgb_valid_dly1 <= rgb_valid;
      rgb_hs_dly1    <= rgb_hs;
      rgb_vs_dly1    <= rgb_vs;
    end
    always@(posedge clk)
    begin
      gray_valid <= rgb_valid_dly1;
      gray_hs    <= rgb_hs_dly1;
      gray_vs    <= rgb_vs_dly1;
    end
如果能将多种实现方法的.v 文件整合到一个模块保存在一个 .v 文件,使用起来就更加的方便。
整合方法1: 宏定义法
通过不同的宏定义条件编译方式进行选择某种实现方式
//`define AVERAGE //求平均法
//`define FORMULA //直接公式法
`define LUT //查找表法
module rgb2gray (
 clk,
 rst_n,
 rgb_valid,
 red_8b_i,
 green_8b_i,
 blue_8b_i,
 gray_8b_o,
 gray_valid
);
`ifdef AVERAGE //求平均法 GRAY=(R+B+G)/3=((R+B+G)*85)>>8
...//方法 1
`endif
`ifdef FORMULA //灰度转换公式 Gray = R*0.299+G*0.587+B*0.114
...//方法 2
`endif
`ifdef LUT//查找表方式
...//方法 3
`endif
endmodule
整合方法2: 使用 generate -if 方法
添加三种方法名称的定义
module rgb2gray
#(
 parameter PROC_METHOD = "AVERAGE" //"AVERAGE" :求平均法
 //or "FORMULA" :直接公式法
 //or "LUT" :查找表法
)
(
 clk, 
 rst_n,
 rgb_valid,
 red_8b_i,
 green_8b_i,
 blue_8b_i,
 gray_8b_o,
 gray_valid
);
generate
 if (PROC_METHOD == "AVERAGE") begin: PROC_AVERAGE
//---------------------------------------------
//求平均法 GRAY = (R+B+G)/3=((R+B+G)*85)>>8
 //方法 1
//---------------------------------------------
 end
 else if (PROC_METHOD == "FORMULA") begin: PROC_FORMULA
//---------------------------------------------
//典型灰度转换公式 Gray = R*0.299+G*0.587+B*0.114=(R*77 + G*150 + B*29) >>8
 //方法 2
//---------------------------------------------
 end
 else if(PROC_METHOD == "LUT") begin: PROC_LUT
//---------------------------------------------
//查找表方式,可以省去公式法中乘法运算 Gray =(R*77 + G*150 + B*29) >>8,将 3 个分量
乘以系数后的数值存储在 ROM 中
 //方法 3
//---------------------------------------------
 end
endgenerate
endmodule
以上两种方法直接在例化模块时就可通过 重定义参数 PROC_METHOD 实现不同方法的设置,例化:
 rgb2gray
 #(
 .PROC_METHOD("FORMULA") //"AVERAGE" :求平均法
 //or "FORMULA" :直接公式法
 //or "LUT" :查找表法
 )rgb2gray_average
 (
 .clk (clk ),
 . reset_p (reset_p ),
 .rgb_valid (rgb_valid ),
 .red_8b_i (red_8b_i ),
 .green_8b_i(green_8b_i),
 .blue_8b_i (blue_8b_i ),
 .gray_8b_o (gray_8b_o ),
 .gray_valid(gray_valid)
 );

记录学习过程,搬运于小梅哥的文档,非原创!!侵权请联系删除。文章来源地址https://www.toymoban.com/news/detail-798462.html

到了这里,关于图像预处理算法————灰度化处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 计算机视觉任务图像预处理之去除图像中的背景区域-------使用连通域分析算法(包含完整代码)

    通过连通域分析算法能够找到最大的连通域,即图片的主体部分,然后保存该连通域的最小外接矩阵,即可去除掉无关的背景区域 更多图像预处理操作工具集包含在这个github仓库中

    2024年02月06日
    浏览(55)
  • 图像预处理方法

    两个基本的形态学操作是腐 和膨胀。他们 的变体构成了开运算 ,闭运算, 梯度等。 根据卷积核的大小前景的所有像素会腐 掉 变为 0 ,所以前景物体会变小整幅图像的白色区域会减少。 对于去除白噪声很有用 也可以用来断开两个 在一块的物体等。 函数原型: ⚫src: 输入原

    2023年04月11日
    浏览(39)
  • 【第十七届智能车】智能车图像处理(1)-图像预处理

    本博客使用的硬件是逐飞总钻风130°无畸变摄像头,采用的图像分辨率为188*120,主控为CH32V307VCT6,使用DVI接口进行连接。 我们在本次比赛中采用的是头尾车总钻风摄像头+中间车线性CCD的方案。这两个感光部件各有优劣,使用方式和图像处理也大相径庭。这里讨论的是总钻风

    2024年02月08日
    浏览(50)
  • 使用 SKimage 的图像预处理

    介绍 图像是视觉对象的二维表示,例如照片、绘画或素描。在数字成像中,图像存储为像素值数组,其中每个像素代表图像亮度和颜色的样本。每个像素的颜色可以由一个或多个通道表示,如传统彩色图像中的红色、绿色和蓝色 (RGB) 通道。在本文中,你将学习各种图像预处

    2024年02月03日
    浏览(55)
  • 关于图像分割的预处理 transform

    目录 1. 介绍 2. 关于分割中的 resize 问题 3. 分割的 transform 3.1 随机缩放 RandomResize 3.2 随机水平翻转 RandomHorizontalFlip 3.3 随机竖直翻转 RandomVerticalFlip 3.4 随机裁剪 RandomCrop 3.5 ToTensor 3.6 normalization 3.7 Compose 3.8 中心裁剪 3.9 Resize 缩放 4. 预处理结果可视化 图像分割的预处理不像

    2024年02月04日
    浏览(50)
  • 图像预处理 Tricks【1】:Contours

    轮廓可以简单地理解为连接所有连续点(沿物体边界)的曲线,这些点通常具有相同的颜色或强度。 轮廓在图像分析中具有重要意义,是物体形状分析和对象检测和识别的有用工具,是理解图像语义信息的重要依据。 本文主要介绍了在 opencv 中,一些重要的用于处理物体轮廓

    2024年02月11日
    浏览(46)
  • 计算机视觉(2)——图像预处理

    二、图像预处理 2.1 介绍  2.2 特征提取方法 2.2.1 直方图 2.2.2 CLAHE 2.2.3 形态学运算 2.2.4 空间域处理及其变换 2.2.5 空间域分析及变换  (1) 均值滤波 (2)中值滤波 (3)高斯滤波 (4) 梯度Prewitt滤波 (5) 梯度Sobel滤波 (6) 梯度Laplacian滤波 (7) 其他滤波  2.2.6 频域分

    2024年02月03日
    浏览(63)
  • OpenCV图像预处理常用函数及流程

    在PyCharm终端中,运行如下命令 由于默认使用的为外网资源,下载速度和稳定性较差,具体看网络状态。如下命令为使用清华镜像下载安装相应的包 在终端中运行命令时,Windows10系统可能会存在如下报错:无法加载激活文件,因此在此系统上禁止运行脚本。此情况是因为win

    2024年02月05日
    浏览(51)
  • 【CV学习笔记】图像预处理warpaffine

    在学习图像预处理的时候发现,之前用的图像预处理方法一般为 resize和letter box,这两种方法比较低效,后来在手写AI中接触到了warpaffine,只需要一步就能够对图像进行预处理,同时还能很方便的进行cuda加速,于是便记录下来。 欢迎正在学习或者想学的CV的同学进群一起讨论与

    2023年04月08日
    浏览(48)
  • 【Computer Vision】图像数据预处理详解

    活动地址:[CSDN21天学习挑战赛](https://marketing.csdn.net/p/bdabfb52c5d56532133df2adc1a728fd) 作者简介 :在校大学生一枚,华为云享专家,阿里云星级博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高等学校计算机教学与产业实践资源建设专家委员会(TIPCC)志愿者,以及编程

    2024年02月06日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包