前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于FPGA的直方图拉伸

基于FPGA的直方图拉伸

作者头像
FPGA开源工作室
发布2019-12-18 17:23:36
1.1K0
发布2019-12-18 17:23:36
举报
文章被收录于专栏:FPGA开源工作室FPGA开源工作室

基于FPGA的直方图拉伸

1 背景知识

在视频处理中,为了能够实时调节图像的对比对,通常需要对直方图进行拉伸处理。直方图拉伸是指将图像灰度直方图较窄的灰度级区间向两端拉伸,增强整幅图像像素的灰度级对比度,达到增强图像的效果。

常用的直方图拉伸方法有线性拉伸、3段式分段线性拉伸和非线性拉伸等。FPGA中常见的是线性拉伸。

线性拉伸就是灰度拉伸,属于线性点运算的一种。它扩展图像的直方图,使其充满整个灰度级范围内。

设f(x,y) 为输入图像,它的最小灰度级A和最大灰度级B的定义如下:

A=min[f(x,y)];

B=max[f(x,y)];

将A和B分别映射到0和255,则最终的输出图像g(x,y)为

g(x,y)=255*[f(x,y)-A]/(B-A)

如上图所示,上a和下a分别为未进行拉伸的原始图像和直方图,上b和下b为拉伸后的图像和直方图。很容易发现直方图分布较窄的a图像经过拉伸后直方图变宽而且对比度明显提高。

2 matlab实现直方图拉伸

代码语言:javascript
复制
close all
clear all;
clc;
I = imread('car0.bmp');
Igray = rgb2gray(I);
Imin=min(min(Igray));
Imax=max(max(Igray));
HW = size(Igray);
H =HW(1);
W =HW(2);
C =255/(Imax-Imin);
Inew = zeros(size(Igray));
for i=1:H
 for j=1:W
 if(Igray(i,j)==Imin)
           Inew(i,j)=0;
 elseif(Igray(i,j)==Imax)
           Inew(i,j)=255;
 else
           Inew(i,j)=(C.*(Igray(i,j)-Imin));
 end
 end
end
Inew = uint8(Inew);
figure(1),
subplot(221),imshow(Igray);
title('Igray');
subplot(223),imshow(Inew);
title('Inew');
subplot(222),imhist(Igray);
title('Igray');
subplot(224),imhist(Inew);
title('Inew');

Matlab实现彩色图像拉伸

代码语言:javascript
复制
close all
clear all;
clc;
 
I = imread('lena.jpg');
Istretch=HistRGB(I);
 
figure(1),
subplot(211),imshow(I);
title('I');
subplot(212),imshow(Istretch);
代码语言:javascript
复制
function [OUT] = HistRGB(I)
    for i = 1:3
        I(:,:,i) = HistGray(I(:,:,i));
    end
    OUT = uint8(I);
end
代码语言:javascript
复制
function [Inew] = HistStretch(Igray)
Imin=min(min(Igray));
Imax=max(max(Igray));
 
HW = size(Igray);
H =HW(1);
W =HW(2);
C =255/(Imax-Imin);
Inew = zeros(size(Igray));
for i=1:H
   for j=1:W
       if(Igray(i,j)==Imin)
           Inew(i,j)=0;
       elseif(Igray(i,j)==Imax)
           Inew(i,j)=255;
       else
           Inew(i,j)=(C.*(Igray(i,j)-Imin));
       end
   end
end
Inew = uint8(Inew);
end

3 FPGA实现灰度图像拉伸

FPGA实现灰度图像的拉伸可分为真拉伸和伪拉伸,真拉伸需要对图像进行一帧的缓存,伪拉伸其实是在前一帧计算出最大和最后灰度级的基础上完成当前图像的拉伸处理,这样比较节省资源。

1,计算灰度图像的最大最小灰度级A,B;

2,完成灰度图像的拉伸。

代码语言:javascript
复制
/**********************************
copyright@FPGA OPEN SOURCE STUDIO
微信公众号:FPGA开源工作室
***********************************/
//800*600 =  480000
//Pseudo histogram linear stretch
//Algorithm:g(x,y) = 255*(f(x,y)-A)/(B-A)
//B--Grayscale max
//A--Grayscale min
 
module hist_Stretch#(
       parameter DW = 24
      )(
      input                      pixelclk,
      input                      reset_n,
      input [DW-1:0]    din,//gray888
      input                      i_hsync,
      input                      i_vsync,
      input                      i_de,
  
  output [DW-1:0]dout,//gray out
      output                     o_hsync,
      output                     o_vsync,
      output                     o_de
   );
   
wire [7:0] gray = din[7:0];//gray--8bit
reg  [7:0] gray_r;
reg        vsync_r;
reg        hsync_r;
reg        de_r;
 
wire [7:0]gray_max;//gray max
wire [7:0]gray_min;//gray min
 
wire       vsync_pos = (i_vsync&(!vsync_r));//frame start
wire       vsync_neg = (!i_vsync&vsync_r);  //frame end
assign dout = {gray_r,gray_r,gray_r};
assign o_hsync = hsync_r;
assign o_vsync = vsync_r;
assign o_de = de_r;
 
always @(posedge pixelclk) begin
  vsync_r <= i_vsync;
  hsync_r <= i_hsync;
  de_r <= i_de;
end
 
always @(posedge pixelclk or negedge reset_n)begin
  if(reset_n == 1'b0) begin
gray_r<=0;
  end
  else begin
if(i_de ==1'b1) begin
  if(gray>gray_max)
    gray_r<=8'd255;
  else if(gray<gray_min)
    gray_r<=8'd255;
  else
    //gray_r<=255*(gray-gray_min)/(gray_max-gray_min);
gray_r <=STRETCH(gray,gray_min,gray_max);
end
  end
end
 
minmax#(.DW(8)
      )Uminmax(
      .pixelclk(pixelclk),
      .reset_n(reset_n),
      .din(gray),//gray--8
      .i_hsync(i_hsync),
      .i_vsync(i_vsync),
      .i_de(i_de),
  
  .gray_max(gray_max),//gray max out
  .gray_min(gray_min)//gray min out
   );  
 
function [7:0] STRETCH;
          input [7:0] gray,gray_min,gray_max;
  begin
    STRETCH = 255*(gray-gray_min)/(gray_max-gray_min);
  end
endfunction   
   
endmodule
代码语言:javascript
复制
/*
Module name:  minmax.v
Description:  Get the maximum and minimum gray level of a frame of image
              
Date:         2019/12/02
微信公众号:    FPGA开源工作室
*/
`timescale 1ns/1ps
module minmax#(parameter DW = 8
      )(
      input                      pixelclk,
      input                      reset_n,
      input [DW-1:0]    din,//gray--8
      input                      i_hsync,
      input                      i_vsync,
      input                      i_de,
  
  output reg [DW-1:0]gray_max,//gray max out
  output reg  [DW-1:0]gray_min//gray min out
   );
 
reg [DW-1:0]gray_maxr;//gray max
reg [DW-1:0]gray_minr;//gray min
 
//reg  [7:0] gray_r;
reg        vsync_r;
reg de_r;
 
wire       vsync_pos = (i_vsync&(!vsync_r));//frame start
wire       vsync_neg = (!i_vsync&vsync_r);  //frame end
 
always @(posedge pixelclk) begin
  de_r <= i_de;
  vsync_r<=i_vsync;
end
 
always @(posedge pixelclk or negedge reset_n)begin
  if(!reset_n) begin
    gray_maxr<= 8'd0;
gray_minr<= 8'd255;
  end  
  else begin
    if(i_vsync ==1'b1 && i_de ==1'b1) begin
  gray_maxr<= (gray_maxr>din)?gray_maxr:din;
  gray_minr<= (din>gray_minr)?gray_minr:din;    
end
else if(vsync_neg == 1'b1)begin
  gray_max<= gray_maxr;
  gray_min<= gray_minr;
  gray_maxr<= 8'd0;
  gray_minr<= 8'd255;
end
else begin
  gray_max<= gray_max;
  gray_min<= gray_min;
  gray_maxr<= gray_maxr;
  gray_minr<= gray_minr;
end
  end
end
 
 
endmodule

未经拉伸的图像感觉蒙了一层雾,经过拉伸后图像对比度明显增强。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FPGA开源工作室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
媒体处理
媒体处理(Media Processing Service,MPS)是一种云端音视频处理服务。基于腾讯多年音视频领域的深耕,为您提供极致的编码能力,大幅节约存储及带宽成本、实现全平台播放,同时提供视频截图、音视频增强、内容理解、内容审核等能力,满足您在各种场景下对视频的处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档