文章目录
- 前言
- 一、膨胀腐蚀
- 二、Python实现腐蚀算法
- 三、Python实现膨胀算法
- 四、Python实现阈值算法
- 五、FPGA实现腐蚀算法
- 总结
前言
腐蚀是指周围的介质作用下产生损耗与破坏的过程,如生锈、腐烂等。而腐蚀算法也类似一种能够产生损坏,抹去部分像素的算法。
一、膨胀腐蚀
膨胀腐蚀之前需要对图像进行二值化处理,然后进行以下处理。
腐蚀: P = P 1 & P 2 & P 3 & P 4 & P 5 & P 6 & P 7 & P 8 & P 9 P = P1 \& P2 \& P3 \& P4 \& P5 \& P6 \& P7 \& P8 \& P9 P=P1&P2&P3&P4&P5&P6&P7&P8&P9
膨胀: P = P 1 ∣ P 2 ∣ P 3 ∣ P 4 ∣ P 5 ∣ P 6 ∣ P 7 ∣ P 8 ∣ P 9 P = P1 | P2 | P3 | P4 | P5 | P6 | P7 | P8 | P9 P=P1∣P2∣P3∣P4∣P5∣P6∣P7∣P8∣P9
图像二值化如下。
import numpy as np
import matplotlib.pyplot as plt
img = plt.imread("lenna.png")
gray = 0.299 * img[:, :, 0] + 0.587 * img[:, :, 1] + 0.114 * img[:, :, 2]
gray = gray * 255#图像是[0-1]--->[0-255]
bin_image = np.where(gray >= 128, 1, 0)#处理成[0,1]像素
二、Python实现腐蚀算法
def bin_erosion(binary, n):h, w = gray.shapem = int((n - 1) / 2)erosion_image = np.zeros((h, w))for i in range(m, h - m):for j in range(m, w - m):erosion_image[i, j] = binary[i - 1, j - 1] & binary[i - 1, j] & binary[i - 1, j + 1] &\binary[i, j - 1] & binary[i, j] & binary[i, j + 1] & binary[i + 1, j - 1] &\binary[i + 1, j] & binary[i + 1, j + 1]return erosion_image
三、Python实现膨胀算法
def bin_dialtion(binary, n):h, w = gray.shapem = int((n - 1) / 2)dialtion_image = np.zeros((h, w))for i in range(m, h - m):for j in range(m, w - m):dialtion_image[i, j] = binary[i - 1, j - 1] | binary[i - 1, j] | binary[i - 1, j + 1] |\binary[i, j - 1] | binary[i, j] | binary[i, j + 1] | binary[i + 1, j - 1] |\binary[i + 1, j] | binary[i + 1, j + 1]return dialtion_image
四、Python实现阈值算法
阈值算法介于膨胀腐蚀之间,可以调整膨胀腐蚀的程度。
def threshold_method(binary, n, value):h, w = gray.shapem = int((n - 1) / 2)th_image = np.zeros((h, w))for i in range(m, h - m):for j in range(m, w - m):temp = binary[i - 1, j - 1] + binary[i - 1, j] + binary[i - 1, j + 1] +\binary[i, j - 1] + binary[i, j] + binary[i, j + 1] + binary[i + 1, j - 1] +\binary[i + 1, j] + binary[i + 1, j + 1]if temp >= value:th_image[i, j] = 1else:th_image[i, j] = 0return th_image
erosion_image = bin_erosion(bin_image, 3)
dialtion_image = bin_dialtion(bin_image, 3)
th_image = threshold_method(bin_image, 3, 8)
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(2, 2, 1)
ax.set_title("bin image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(bin_image, cmap="gray")
ax = fig.add_subplot(2, 2, 2)
ax.set_title("erosion image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(erosion_image, cmap="gray")
ax = fig.add_subplot(2, 2, 3)
ax.set_title("dialtion image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(dialtion_image, cmap="gray")
ax = fig.add_subplot(2, 2, 4)
ax.set_title("threshold image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(th_image, cmap="gray")
画图结果如下。
五、FPGA实现腐蚀算法
module ycbcr_to_erosion
(input wire vga_clk ,//vga时钟input wire sys_rst_n ,//复位信号input wire [7:0] y_data ,//灰度处理的图像像素input wire rgb_valid ,//vga显示有效区域output wire [15:0] erosion_data //二值化像素
);
//binary data
wire [7: 0] bin_data;//shift ram
wire [7:0] data_row1 ;
wire [7:0] data_row2 ;
wire [7:0] data_row3 ;
//3*3像素数据
reg [7:0] p11 ;
reg [7:0] p12 ;
reg [7:0] p13 ;
reg [7:0] p21 ;
reg [7:0] p22 ;
reg [7:0] p23 ;
reg [7:0] p31 ;
reg [7:0] p32 ;
reg [7:0] p33 ;wire [7:0] temp ;
//Y值有效信号
reg y_valid ;
//二值化
assign bin_data = (y_data >= 8'd128) ? 8'd255: 8'd0;
assign data_row3 = bin_data ;
//腐蚀
assign temp = (p11 & p12 & p13 & p21 & p22 & p23 & p31 & p32 & p33);
//像素拼接565
assign erosion_data = {temp[7:3], temp[7:2], temp[7:3]};
always@(posedge vga_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)y_valid <= 1'b0 ;elsey_valid <= rgb_valid ;always@(posedge vga_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)begin{p11,p12,p13} <= 24'd0 ;{p21,p22,p23} <= 24'd0 ;{p31,p32,p33} <= 24'd0 ;endelse if(y_valid == 1'b1)begin{p11,p12,p13} <= {p12,p13,data_row1} ;{p21,p22,p23} <= {p22,p23,data_row2} ;{p31,p32,p33} <= {p32,p33,data_row3} ;end elsebegin{p11,p12,p13} <= 24'd0 ;{p21,p22,p23} <= 24'd0 ;{p31,p32,p33} <= 24'd0 ;end
//移位寄存器
shift_ram_gen shift_ram_gen_inst
(.clock (vga_clk ),.shiftin (data_row3 ),.shiftout ( ),.taps0x (data_row2 ),.taps1x (data_row1 )
);endmodule
FPGA实现中,只讲解腐蚀算法,膨胀算法及阈值算法,感兴趣的小伙伴可以自行实现,非常easy。
总结
膨胀腐蚀算法图像处理中常用的算法,有必要掌握。虽然简单,还是需要自己去实现,写多了,也就顺了。下期帧差法。帧差法只做Python,不做FPGA,为什么?下期揭晓答案。