Python与FPGA——图像锐化

文章目录

  • 前言
  • 一、图像锐化
  • 二、Python robert锐化
  • 三、Python sobel锐化
  • 四、Python laplacian锐化
  • 五、FPGA sobel锐化
  • 总结


前言

  在增强图像之前一般会先对图像进行平滑处理以减少或消除噪声,图像的能量主要集中在低频部分,而噪声和图像边缘信息的能量主要集中在高频部分。因此,平滑处理会使原始的图像边缘和轮廓变得模糊。为了减少不利效果的影响,需要利用图像锐化技术。


一、图像锐化

  图像锐化其实就是使用robert,sobel,laplacian这些人发明的窗口,进行图像的处理。图像锐化过程和sobel边缘检测的过程类似,可以移步至《Python与FPGA——sobel边缘检测》课程,一探究竟。

一阶微分的边缘检测
  图像f(x, y)在像素(x, y)梯度的定义为
G = ∂ f ∂ x + ∂ f ∂ y G = \frac{\partial f}{\partial x} + \frac{\partial f}{\partial y} G=xf+yf
也可以用差分来替代微分,即
∂ f ∂ x = f ( i + 1 , j ) − f ( i , j ) \frac{\partial f}{\partial x} = f(i + 1, j) - f(i, j) xf=f(i+1,j)f(i,j)
∂ f ∂ y = f ( i , j + 1 ) − f ( i , j ) \frac{\partial f}{\partial y} = f(i, j + 1) - f(i, j) yf=f(i,j+1)f(i,j)
梯度的幅值即模值,为
∣ G ∣ = ( ∂ f ∂ x ) 2 + ( ∂ f ∂ y ) 2 = [ f ( i + 1 , j ) − f ( i , j ) ] 2 + [ f ( i , j ) − f ( i , j ) ] 2 |G| = \sqrt{(\frac{\partial f}{\partial x})^2 + (\frac{\partial f}{\partial y})^2} = \sqrt{[f(i + 1, j) - f(i, j)]^2 + [f(i, j ) - f(i, j)]^2} G=(xf)2+(yf)2 =[f(i+1,j)f(i,j)]2+[f(i,j)f(i,j)]2
梯度方向为
θ = a r c t a n ( ∂ f ∂ y / ∂ f ∂ x ) = a r c t a n [ f ( i , j + 1 ) − f ( i , j ) f ( i + 1 , j ) − f ( i , j ) ] \theta = arctan(\frac{\partial f}{\partial y}/\frac{\partial f}{\partial x}) = arctan[\frac{f(i, j + 1) - f(i, j)}{f(i + 1, j) - f(i, j)}] θ=arctan(yf/xf)=arctan[f(i+1,j)f(i,j)f(i,j+1)f(i,j)]
图像f(i, j)处的梯度g为
g ( i , j ) = G [ f ( i , j ) ] g(i, j) = G[f(i, j)] g(i,j)=G[f(i,j)]
使用 g ( i , j ) g(i, j) g(i,j)去替代原来的像素。
  一阶导算子有robert算子,perwitt算子,sobel算子。
1. Roberts算子
G x = [ 1 0 0 − 1 ] G y = [ 0 − 1 1 0 ] G_x = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} \quad\quad\quad G_y = \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix} Gx=[1001]Gy=[0110]
2. Prewitt算子
G x = [ − 1 0 1 − 1 0 1 − 1 0 1 ] G y = [ − 1 − 1 − 1 0 0 0 1 1 1 ] G_x = \begin{bmatrix} -1 & 0 & 1\\ -1 & 0 & 1\\ -1 & 0 & 1 \end{bmatrix} \quad\quad\quad G_y = \begin{bmatrix} -1 & -1 & -1\\ 0 & 0 & 0\\ 1 & 1 & 1 \end{bmatrix} Gx=111000111Gy=101101101
3. Sobel算子
G x = [ − 1 0 + 1 − 2 0 + 2 − 1 0 + 1 ] G y = [ + 1 + 2 + 1 0 0 0 − 1 − 2 1 ] G_x = \begin{bmatrix} -1 & 0 & +1\\ -2 & 0 & +2\\ -1 & 0 & +1 \end{bmatrix} \quad\quad\quad G_y = \begin{bmatrix} +1 & +2 & +1\\ 0 & 0 & 0\\ -1 & -2 & 1 \end{bmatrix} Gx=121000+1+2+1Gy=+101+202+101

二阶微分的边缘检测
  二阶微分公式用差分法,推理如下
∂ 2 f ∂ x 2 = 2 f ( x , y ) − f ( x − 1 , y ) − f ( x + 1 , y ) \frac{\partial^2 f}{\partial x^2}=2f(x,y)-f(x-1,y)-f(x+1, y) x22f=2f(x,y)f(x1,y)f(x+1,y)
∂ 2 f ∂ y 2 = 2 f ( x , y ) − f ( x , y − 1 ) − f ( x , y + 1 ) \frac{\partial^2 f}{\partial y^2}=2f(x,y)-f(x,y-1)-f(x, y+1) y22f=2f(x,y)f(x,y1)f(x,y+1)
▽ 2 f = 4 f ( x , y ) − [ f ( x − 1 , y ) + f ( x , y − 1 ) + f ( x , y + 1 ) + f ( x + 1 , y ) ] \triangledown^2f=4f(x,y)-[f(x-1,y)+f(x,y-1)+f(x,y+1)+f(x+1,y)] 2f=4f(x,y)[f(x1,y)+f(x,y1)+f(x,y+1)+f(x+1,y)]
符合二阶微分的算子是laplacian。

G x = [ 0 − 1 0 − 1 4 − 1 0 − 1 0 ] G y = [ − 1 − 1 − 1 − 1 8 − 1 − 1 − 1 − 1 ] G_x = \begin{bmatrix} 0 & -1 & 0\\ -1 & 4 & -1\\ 0 & -1 & 0 \end{bmatrix} \quad\quad\quad G_y = \begin{bmatrix} -1 & -1 & -1\\ -1 & 8 & -1\\ -1 & -1 & -1 \end{bmatrix} Gx=010141010Gy=111181111

二、Python robert锐化

import numpy as np
import matplotlib.pyplot as plt
def image_gray(image):
    gray = np.dot(image[:, :, ...], [0.299, 0.587, 0.114])#等同0.299 * image[:, :, 0] + 0.587 * image[:, :, 1] + 0.114 * image[:, :, 2]
    return gray.astype(np.uint8)
    
def robert_sharpen(image, gx, gy):
    h, w = image.shape
    n, n = gx.shape
    filtered_image = np.zeros((h, w))
    m = int(n / 2)
    for i in range(m, h - m):
        for j in range(m, w - m):   
            gx_value = np.sum(np.multiply(gx, image[i - m: i + m, j - m: j + m]))
            gy_value = np.sum(np.multiply(gy, image[i - m: i + m, j - m: j + m]))
            gxy_value = np.sqrt(gx_value ** 2 + gy_value ** 2)
            filtered_image[i, j] = gxy_value
    return filtered_image.astype(np.uint8)
    
img = plt.imread("lenna.png")
img = img * 255#图像是[0-1]--->[0-255],确认一下自己的图像是[0-1]还是[0-255]
img = img.astype(np.uint8)
gx = np.array([[1, 0],
               [0, -1]])
gy = np.array([[0, 1],
               [-1, 0]])
gray = image_gray(img)
robert_image = robert_sharpen(gray, gx, gy)
fig = plt.figure(figsize=(10, 6))
ax = plt.subplot(1, 2, 1)
ax.set_title("raw image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(gray, cmap="gray")
ax = plt.subplot(1, 2, 2)
ax.set_title("robert image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(robert_image, cmap="gray")

在这里插入图片描述

三、Python sobel锐化

import numpy as np
import matplotlib.pyplot as plt
def image_gray(image):
    gray = np.dot(image[:, :, ...], [0.299, 0.587, 0.114])#等同0.299 * image[:, :, 0] + 0.587 * image[:, :, 1] + 0.114 * image[:, :, 2]
    return gray.astype(np.uint8)
    
def sobel_sharpen(image, gx, gy):
    h, w = image.shape
    n, n = gx.shape
    filtered_image = np.zeros((h, w))
    m = int((n-1) / 2)
    for i in range(m, h - m):
        for j in range(m, w - m):   
            gx_value = np.sum(np.multiply(gx, image[i - m: i + m + 1, j - m: j + m + 1]))
            gy_value = np.sum(np.multiply(gy, image[i - m: i + m + 1, j - m: j + m + 1]))
            gxy_value = np.sqrt(gx_value ** 2 + gy_value ** 2)
            filtered_image[i, j] = gxy_value
    return filtered_image.astype(np.uint8)
    
img = plt.imread("lenna.png")
img = img * 255#图像是[0-1]--->[0-255],确认一下自己的图像是[0-1]还是[0-255]
img = img.astype(np.uint8)
gx = np.array([[-1, 0, 1],
               [-2, 0, 2],
               [-1, 0, 1]])
gy = np.array([[-1, -2, -1],
               [0, 0, 0],
               [1, 2, 1]])
gray = image_gray(img)
sobel_image = sobel_sharpen(gray, gx, gy)
fig = plt.figure(figsize=(10, 6))
ax = plt.subplot(1, 2, 1)
ax.set_title("raw image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(gray, cmap="gray")
ax = plt.subplot(1, 2, 2)
ax.set_title("sobel image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(sobel_image, cmap="gray")

在这里插入图片描述

四、Python laplacian锐化

import numpy as np
import matplotlib.pyplot as plt
def image_gray(image):
    gray = np.dot(image[:, :, ...], [0.299, 0.587, 0.114])#等同0.299 * image[:, :, 0] + 0.587 * image[:, :, 1] + 0.114 * image[:, :, 2]
    return gray.astype(np.uint8)
    
def laplacian_sharpen(image, gx, gy):
    h, w = image.shape
    n, n = gx.shape
    filtered_image = np.zeros((h, w))
    m = int((n-1) / 2)
    for i in range(m, h - m):
        for j in range(m, w - m):   
            gx_value = np.sum(np.multiply(gx, image[i - m: i + m + 1, j - m: j + m + 1]))
            gy_value = np.sum(np.multiply(gy, image[i - m: i + m + 1, j - m: j + m + 1]))
            gxy_value = np.sqrt(gx_value ** 2 + gy_value ** 2)
            filtered_image[i, j] = gxy_value
    return filtered_image.astype(np.uint8)
    
img = plt.imread("lenna.png")
img = img * 255#图像是[0-1]--->[0-255],确认一下自己的图像是[0-1]还是[0-255]
img = img.astype(np.uint8)
gx = np.array([[0, -1, 0],
               [-1, 4, -1],
               [0, -1, 0]])
gy = np.array([[-1, -1, -1],
               [-1, 8, -1],
               [-1, -1, -1]])
gray = image_gray(img)
sobel_image = sobel_sharpen(gray, gx, gy)
fig = plt.figure(figsize=(10, 6))
ax = plt.subplot(1, 2, 1)
ax.set_title("raw image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(gray, cmap="gray")
ax = plt.subplot(1, 2, 2)
ax.set_title("sobel image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(sobel_image, cmap="gray")

在这里插入图片描述

五、FPGA sobel锐化

//3*3图像
//P11   P12   P13
//P21   P22   P23
//P31   P32   P33

//Gx算子
//-1     0     1
//-2     0     2
//-1     0     1
//Gx = -P11 + P13 - 2*P21 + 2*P23 - P31 + P33
//Gx = (P13 - P11) + 2*(P23 - P21) + (P33 - P31)

//Gy算子
//1      2     1
//0      0     0
//-1     -2    -1
//Gy = P11 + 2*P12 + P13 - P31 - 2*P32 - P33
//Gy = (P11 - P31) + 2*(P12 - P32) + (P13 - P33)
module  ycbcr_sobel_sharpen
(
	input	wire			sys_clk		,	//系统时钟,频率为50MHZ
	input	wire			sys_rst_n	,	//系统复位,低电平有效
	input	wire			rgb_valid	,	//RGB565图像显示有效信号
	input	wire	[7:0]	y_data		,	//Y分量
	input	wire	[11:0]	pixel_x		,	//有效显示区域横坐标
	input	wire	[11:0]	pixel_y		,	//有效显示区域纵坐标
	
	output	reg		[15:0]	sobel_data		//Sobel算法处理后的图像数据
);

reg				y_valid		;	//Y分量有效信号
//shift ram
wire	[7:0]	data_row1	;	//移位寄存器第一行数据
wire	[7:0]	data_row2	;	//移位寄存器第二行数据
wire	[7:0]	data_row3	;	//移位寄存器第三行数据
//3*3像素数据,左上角至右下角共9个数据
reg		[7:0]	p11			;	//3*3第1个像素数据
reg		[7:0]	p12			;	//3*3第2个像素数据
reg		[7:0]	p13			;	//3*3第3个像素数据
reg		[7:0]	p21			;	//3*3第4个像素数据
reg		[7:0]	p22			;	//3*3第5个像素数据
reg		[7:0]	p23			;	//3*3第6个像素数据
reg		[7:0]	p31			;	//3*3第7个像素数据
reg		[7:0]	p32			;	//3*3第8个像素数据
reg		[7:0]	p33			;	//3*3第9个像素数据
//Sobel算子
wire	[15:0]	Gx			;	//水平梯度值
wire	[15:0]	Gy			;	//数值梯度值
wire	[7:0]	Gxy			;	//总体梯度值

assign  data_row3 = y_data  ;
assign  Gx = (p13 - p11) + 2*(p23 - p21) + (p33 - p31)  ;
assign  Gy = (p11 - p31) + 2*(p12 - p32) + (p13 - p33)  ;

//设定第一行、第二行,第一列、第二列显示全白色
always@(*)
	if((pixel_y == 12'd0)||(pixel_y == 12'd1)||(pixel_x == 12'd2)||(pixel_x == 12'd3))
		sobel_data = 16'hffff  ;
	else
		sobel_data = {Gxy[7:3],Gxy[7:2],Gxy[7:3]}  ;//锐化核心代码

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		y_valid  <=  1'b0  ;
	else
		y_valid  <=  rgb_valid  ;

always@(posedge sys_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  ;
		end
	else  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	
	else
		begin
			{p11,p12,p13}  <=  24'd0  ;
			{p21,p22,p23}  <=  24'd0  ;
			{p31,p32,p33}  <=  24'd0  ;
		end		

shift_ram_gen  shift_ram_gen_inst
(
	.clock 		(sys_clk	),
	.shiftin	(data_row3	),
	.shiftout 	(			),
	.taps0x 	(data_row2	),
	.taps1x 	(data_row1	)
);

sqrt_gen  sqrt_gen_inst 
(
	.radical	(Gx*Gx + Gy*Gy),
	.q 			(Gxy	),
	.remainder 	()
);

endmodule

在这里插入图片描述


总结

  图像锐化就到此结束,剩下的交给小伙伴自行实现。Python的prewitt实现;FPGA的robert、prewitt、laplacian算子实现,你都可以尝试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/439702.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 生成与解析Jwt

Spring Boot 生成与解析Jwt Maven依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency>生成&解析 package yang;import io.jsonwebtoken.Claims…

DDS技术概述及测试策略与方案

随着车载通信技术的快速发展&#xff0c;传统的通信技术在满足车载通信需求方面面临着一些挑战。车载通信对实时性、可靠性以及通信带宽的需求越来越高&#xff0c;同时车载通信环境存在多路径衰落、信号干扰等问题&#xff0c;这些都给通信技术的选择和应用带来了一定的挑战。…

沐风老师3DMAX快速布尔QuickBoolean插件安装和使用教程

3DMAX快速布尔QuickBoolean插件安装和使用教程 3DMAX快速布尔QuickBoolean插件是一组工具&#xff0c;用于对具有预设轮廓的当前选定对象快速执行ProBoolean运算&#xff0c;如并集、相交、空心、修剪、减法、拆分和刀。 它的工作原理与SketchUp的Solid Tools非常相似&#xf…

qt如何配置ros环境

在Qt5.7的版本可以使用bash -i -c来启动qt&#xff0c;让Qt自己识别系统环境&#xff0c;不知道为什么Qt在之后的版本&#xff0c;这样使用都失效了。因为它会默认把CMAKE_PREFIX_PATH修改掉。 网上还有安装ros插件版本的qt creator&#xff0c;感觉失去了一些灵活性。 自己测试…

STM32CubeIDE基础学习-STM32CubeIDE软件配置下载器方法

STM32CubeIDE基础学习-STM32CubeIDE软件配置下载器方法 文章目录 STM32CubeIDE基础学习-STM32CubeIDE软件配置下载器方法前言第1章 配置ST-LINK下载器第2章 配置DAP下载器总结 前言 这个软件编译完之后&#xff0c;可以使用下载器进行在线下载程序或仿真调试程序&#xff0c;也…

高效办公-电脑软件安装简介

之前大概了解了一下应用软件就是在操作系统上面安装的一些办公软件。今天来学习下怎么下载软件、怎么安装、怎样卸载&#xff1f; 一、软件类型 电脑操作系统上可以根据自己的需求按照许多软件实现办公、影音娱乐等功能&#xff0c;大概分类有下面的一些&#xff0c;但是只是一…

设计模式(十):抽象工厂模式(创建型模式)

Abstract Factory&#xff0c;抽象工厂&#xff1a;提供一个创建一系列相关或相互依赖对 象的接口&#xff0c;而无须指定它们的具体类。 之前写过简单工厂和工厂方法模式(创建型模式)&#xff0c;这两种模式比较简单。 简单工厂模式其实不符合开闭原则&#xff0c;即对修改关闭…

Linux:kubernetes(k8s)允许在任意节点使用kubectl命令(5)

我们部署好了主节点以后&#xff0c;我们使用kubectl命令 一切正常&#xff0c;而我们到了别的node上使用 就显示一个这个 这个原因是因为我们开始就配置了master的一个配置文件&#xff0c;在/root/.kube/config 里&#xff0c;而我们的从节点不知道去找那个api接口所以就报…

一分钟安装使用教程,无需服务器,一台电脑就可使用!全网最快速便捷使用Claude 3方法!

随着AI的应用变广&#xff0c;各类AI程序已逐渐普及&#xff0c;尤其是在一些日常办公、学习等与撰写/翻译文稿密切相关的场景&#xff0c;大家都希望找到一个适合自己的稳定可靠的ChatGPT软件来使用。 ChatGPT-Next-Web就是一个很好的选择。它是一个Github上超人气的免费开源…

【mogoose】对查询的数据进行过滤不需要展示的信息

数据库结构如下 我只要email userName sex role 几个数据&#xff0c;其余不要 {_id: new ObjectId(65e7b6df8d06a0623fa899f5),email: 12345qq.com,pwd: $2a$10$eLJ9skKEsQxvzHf5X8hbaOXKtg8GCHBeieieSN6Usu17D2DPaI44i,userName: 默认昵称0769,sex: 0,token: {upCount: 0,_…

想交易盈利?Anzo Capital昂首资本发现了一本畅销书

要想在复杂多变的外汇市场中迅速加深了解并想通过交易每天都可以盈利&#xff0c;是通过每天阅读大量的书籍吗&#xff1f;是每天成为行业培训网络资源和论坛的常客吗&#xff1f;是通过花钱请有经验的交易者进行个人培训吗&#xff1f;还是进行EA交易呢&#xff1f; 都不是&a…

C# LINQ基础

LINQ基础 1. 入门2. 运算符流语法2.1 连续使用查询运算符2.2 使用Lambda表达式2.2.1 Lambda表达式及Func的方法签名2.2.2 Lambda表达式和元素类型2.2.3 自然排序2.2.4 其他查询运算符 3 查询表达式4 延迟执行4.1 重复执行4.2 捕获的变量4.3 延迟加载的工作原理4.4 查询语句的执…

如何将TIDB作为Mysql的从库实现实时数据同步

------------------------------------------------------------------- 欢迎关注作者 墨天伦:潇湘秦的个人主页 - 墨天轮 CSDN:潇湘秦-CSDN博客 公众号:潇湘秦的DBA之路 ------------------------------------------------------------------- 近期一个MES项目架构比较复…

Spark实战-基于Spark日志清洗与数据统计以及Zeppelin使用

Saprk-日志实战 一、用户行为日志 1.概念 用户每次访问网站时所有的行为日志(访问、浏览、搜索、点击)用户行为轨迹&#xff0c;流量日志2.原因 分析日志&#xff1a;网站页面访问量网站的粘性推荐3.生产渠道 (1)Nginx(2)Ajax4.日志内容 日志数据内容&#xff1a;1.访问的…

IOS降级后从高版本到低版本恢复备份

IOS降级后从高版本到低版本恢复备份 此方法只适用于小版本还原&#xff0c;比如17.4->17.3&#xff0c;未验证大版本恢复可行性手机型号&#xff1a;iphone 13pro 系统版本&#xff1a;17.4 降级版本&#xff1a;17.3.1 步骤 通过itunes或者MacOS系统下对当前版本进行备份…

Windows11安装FFmpeg最新版本

打开终端: 输入 winget install ffmpeg 然后输入 Y 回车后出现如下图: 正在下载FFmpeg 6.1 安装成功 测试

常见数据类型

目录 数据类型 字符串 char nchar varchar varchar2 nvarchar 数字 number integer binary_float binary_double float 日期 date timestamp 大文本数据 大对象数据 Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 数…

Python实现时间序列分析Theta模型(ThetaModel算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 时间序列分析中的Theta模型(Theta Model)是由Athanasios Theodoridis在2008年提出的一种统计预测方法&…

Java中SpringBoot四大核心组件是什么

一、Spring Boot Starter 1.1 Starter的应用示例 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency><groupId>org.mybatis.sprin…

代码随想录算法训练营第十七天 | 110.平衡二叉树,257. 二叉树的所有路径,404.左叶子之和

递归法&#xff0c;考虑当我站在一个节点上时&#xff0c;我应该干点啥&#xff0c;是不是想知道是否是平衡二叉树&#xff0c;就得知道左右子树的高度&#xff0c;进一步判断这个节点下是不是平衡的&#xff0c;天然的就是一个后序遍历的场景&#xff0c;从左右子树收集信息 …