Python与FPGA——全局二值化

news2025/1/24 1:38:27

文章目录

  • 前言
  • 一、Python全局128
  • 二、Python全局均值
  • 三、Python全局OTSU
  • 四、FPGA全局128
  • 总结


前言

  为什么要进行图像二值化,rgb图像有三个通道,处理图像的计算量较大,二值化的图像极大的减少了处理图像的计算量。即便从彩色图像转成了二值化图像,也不影响对物体的识别。本章开始讲解图像二值化。Python包含全局128、全局均值、大津阈值法(OTSU);FPGA只做全局128的讲解。


一、Python全局128

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, 255, 0)#全局二值化
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(1, 2, 1)
ax.set_title("gray image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(gray, cmap="gray")
ax = fig.add_subplot(1, 2, 2)
ax.set_title("binary image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(bin_image, cmap="gray")

在这里插入图片描述


二、Python全局均值

mean_image = np.where(gray > np.mean(gray), 255, 0)#全局均值
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(1, 2, 1)
ax.set_title("gray image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(gray, cmap="gray")
ax = fig.add_subplot(1, 2, 2)
ax.set_title("mean image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(mean_image, cmap="gray")

在这里插入图片描述


三、Python全局OTSU

  OTSU是阈值分割中一种常用的算法,它可以根据图像自动生成最佳分割阈值。 OTSU的核心思想是类间方差最大化。

  1. 初始化一个阈值T0,将图像分为前景f和背景b;
  2. 图像像素点个数为图像N=height x width,前景像素个数Nf,背景像素个数Nb;
  3. 图像灰度等级L-1(0~255=256),每个灰度等级像素个数Ni,满足以下公式:

P f = ∑ i = 0 i = T 0 N i N P b = ∑ i = T 0 i = L − 1 N i N (1) Pf = \sum_{i = 0}^{i=T0}\frac{Ni}{N} \quad\quad Pb= \sum_{i = T0}^{i=L-1}\frac{Ni}{N}\tag{1} Pf=i=0i=T0NNiPb=i=T0i=L1NNi(1)

  1. 前景和背景的灰度平均值分别为:

M f = ∑ i = 0 i = T 0 i × P i P f M b = ∑ i = T 0 i = L − 1 i × P i P b (2) Mf = \sum_{i = 0}^{i=T0}i \times \frac{Pi}{Pf} \quad\quad Mb= \sum_{i = T0}^{i=L-1}i\times\frac{Pi}{Pb}\tag{2} Mf=i=0i=T0i×PfPiMb=i=T0i=L1i×PbPi(2)

  1. 整个图像灰度平均值:
    M = P f × M f + P b × M b (3) M = Pf \times Mf + Pb \times Mb\tag{3} M=Pf×Mf+Pb×Mb(3)

  2. 求前景和背景之间的方差:
    σ 2 = P f × ( M f − M ) 2 + P b × ( M b − M ) 2 (4) \sigma^2 = Pf\times(Mf-M)^2 + Pb \times(Mb-M)^2\tag{4} σ2=Pf×(MfM)2+Pb×(MbM)2(4)

  3. 找到阈值T0,使得公式4最大;

  4. 怎么找?可以采用优化算法,本文中直接遍历灰度等级,查找最优阈值。

"""
统计像素点函数
image: 输入灰度图(ndarray)
reutrn: {像素:个数}(dict)
"""
def pixel_num(image):
    h, w = image.shape
    pdict = {}
    for i in range(h):
        for j in range(w):
            if image[i,j] in pdict:
                pdict[image[i,j]] += 1
            else:
                pdict[image[i,j]] = 0
    return pdict

"""
求公式4中sigma2的值
T0: 预设阈值(int)
gray: 灰度图(ndarray)
L: 灰度等级(int)
"""
def sigma2(T0, gray, L=256):
    h, w = gray.shape
    N = h * w
    pdict = pixel_num(gray)
    pf = sum([v for k,v in pdict.items() if k < T0]) / N#公式1
    pb = sum([v for k,v in pdict.items() if k >= T0]) / N#公式1
    pf = [pf if pf > 1e-6 else 1e-6][0]#控制最小值,避免除以0
    pb = [pb if pb > 1e-6 else 1e-6][0]#控制最小值,避免除以0
    mf = sum([k * pdict.get(k, 0) / N for k in range(T0)]) / pf#公式2
    mb = sum([k * pdict.get(k, 0) / N for k in range(T0, L)]) / pb#公式2
    M = pf * mf + pb * mb#公式3
    s2 = pf * (mf - M) ** 2 + pb * (mb - M) ** 2#公式4
    return s2, T0

"""
遍历查找最大sigma2
gray: 灰度图(ndarray)
L: 灰度等级(int)
"""
def otsu(gray, L=256):
    smax = 0
    tmax = 0
    for t in range(1, L):
        s2, T0 = sigma2(t, gray, L)
        if s2 > smax:
            smax = s2
            tmax = T0
    return smax, tmax

"""
根据最佳阈值求二值化图像
threshold: 最佳阈值(int)
return: 二值化图像(ndarray)
"""
def otsu_threshold(max_threshold, gray):
    threshold = np.mean(gray)
    binary = np.where(gray >= max_threshold, 255, 0)
    return binary
    
smax, tmax = otsu(gray, 256)  
otsu_image = otsu_threshold(tmax, gray)
plt.figure(figsize=(10,10))
ax = plt.subplot(1, 2, 1)
ax.set_title("gray image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(gray, cmap="gray")
ax = plt.subplot(1, 2, 2)
ax.set_title("otsu image")
ax.set_xlabel("width")
ax.set_ylabel("height")
plt.imshow(otsu_image, cmap="gray")

在这里插入图片描述
  大津阈值法计算量较大,FPGA实现没有意义。


四、FPGA全局128

module  ycbcr2binary_global
(
	input	wire			vga_clk		,
	input	wire			sys_rst_n	,
	input	wire	[7:0]	y_data	    ,
    input   wire            rgb_valid   ,

	output	reg		[15:0]	binary_data
);
wire [7: 0] temp;
reg        y_valid;
assign temp = (y_data >= 8'd128)? 8'd255: 8'd0;	

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

always@(posedge vga_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		binary_data  <=  16'd0  ;
	else if(y_valid == 1'b1)
		binary_data  <=  {temp[7:3], temp[7:2], temp[7:3]};
    else
        binary_data <= binary_data;
endmodule

在这里插入图片描述


总结

  全局二值化都比较基础,Python与FPGA实现都较为简单。下期讨论难度升级的局部二值化,敬请期待。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HarmonyOS应用开发-环境搭建(windows环境)

官网地址&#xff1a;链接 DevEco Studio 3.1.1 Release&#xff1a;下载地址 1、安装DevEco Studio 直接安装即可 2、配置开发环境 1.运行已安装的DevEco Studio&#xff0c;首次使用&#xff0c;请选择Do not import settings&#xff0c;单击OK。 2.安装Node.js与ohpm。注…

STC89C52串口通信详解

目录 前言 一.通信基本原理 1.1串行通信与并行通信 1.2同步通信和异步通信 1.2.1异步通信 1.2.2同步通信 1.3单工、半双工与全双工通信 1.4通信速率 二.串口通信简介 2.1接口标准 2.2串口内部结构 2.3串口相关寄存器 三.串口工作方式 四.波特率计算 五.串口初始化步骤 六.实验…

【go语言开发】gorm库连接和操作mysql,实现一个简单的用户注册和登录

本文主要介绍使用gorm库连接和操作mysql&#xff0c;首先安装gorm和mysql依赖库&#xff1b;然后初始化mysql&#xff0c;配置连接池等基本信息&#xff1b;然后建表、完成dao、controller开发&#xff1b;最后在swagger中测试 文章目录 前言安装依赖库数据库初始化账号注册和登…

Hadoop运行搭建——系统配置和Hadoop的安装

Hadoop运行搭建 前言&#xff1a; 本文原文发在我自己的博客小站&#xff0c;直接复制文本过来&#xff0c;所以图片不显示(我还是太懒啦&#xff01;)想看带图版的请移步我的博客小站~ Linux镜像&#xff1a;CentOS7 系统安装&#xff1a;CentOS安装参考教程 系统网卡设置…

在win10中下载桌面版的docker并在docker中搭建运行基于linux的容器

在win10中下载桌面版的docker 1.背景 在很多时候需要linux系统部署项目&#xff0c;在win10中安装虚拟机并在虚拟机中安装linux系统比较繁琐&#xff0c;可以利用win10自带的hyper-v的虚拟机管理工具&#xff0c;打开该虚拟机管理工具&#xff0c;安装docker&#xff0c;并在…

【排序】希尔排序

一、思想 希尔排序&#xff0c;由D.L. Shell于1959年提出&#xff0c;是基于插入排序的一种改进算法。它的主要思想是将待排序的序列分割成若干个子序列&#xff0c;这些子序列的元素是相隔一定“增量”的。然后对每个子序列进行直接插入排序。随着增量的逐步减小&#xff0c;…

数学建模【整数规划】

一、整数规划简介 整数规划其实是线性规划和非线性规划的一个特殊情况&#xff0c;即有的变量取值只能是整数&#xff0c;不能是小数。这时候就需要一个新的函数来解决问题。 对于整数规划&#xff0c;分为线性整数规划和非线性整数规划 线性整数规划&#xff1a;MATLAB可进…

gitlab仓库迁移至bitbucket

0. 场景描述 假设已有一个gitlab仓库&#xff1a;ssh://xxx_origin.git&#xff0c;想要把这个仓库迁移至bitbucket上。 默认gitlab和bitbucket的SSH key都已添加。 1. 新建bitbucket仓库 在bitbucket上创建新的仓库&#xff0c;并复制url地址。假设为&#xff1a; https:/…

Leetcode 26. 删除有序数组中的重复项 java版。 java解决删除重复数组元素并输出长度

1. 官网链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 2. 题目描述&#xff1a; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该…

一个数据库表格缺少自动增加的字段导致添加一条数据失败

一个数据库表格缺少自动增加的字段导致添加一条数据失败。最近要整理出一个cms网站源程序&#xff0c;因此新建了一个目录&#xff0c;将需要的文件复制到该目录。复制好以后&#xff0c;试用的时候发现添加留言失败。经过数小时的查找原因&#xff0c;最后找到原因&#xff0c…

修复通达OA 百度ueditor 文件上传漏动

前些日子&#xff0c;服务器阿里云监控报警&#xff0c;有文件木马文件&#xff0c;因为非常忙&#xff0c;就没及时处理&#xff0c;直接删除了木马文件了事。 谁知&#xff0c;这几天对方又上传了木马文件。好家伙&#xff0c;今天不花点时间修复下&#xff0c;你都传上瘾了…

苍穹外卖学习-----2024/03/04

1.公共字段填充 代码在这里

【python--读取csv文件统计店铺有关信息】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; python练习题 读取csv文件统计店铺有关信息 读取csv文件统计店铺有关信息 import csv import osdef get_…

L1-096 谁管谁叫爹分数

L1-096 谁管谁叫爹 分数 20 全屏浏览 切换布局 作者 陈越 单位 浙江大学 《咱俩谁管谁叫爹》是网上一首搞笑饶舌歌曲&#xff0c;来源于东北酒桌上的助兴游戏。现在我们把这个游戏的难度拔高一点&#xff0c;多耗一些智商。 不妨设游戏中的两个人为 A 和 B。游戏开始后&…

Android开发者值得深入思考的几个问题,腾讯T3大佬亲自教你

前言 众所周知&#xff0c;移动开发已经来到了后半场&#xff0c;为了能够在众多开发者中脱颖而出&#xff0c;我们需要对某一个领域有深入地研究与心得&#xff0c;对于Android开发者来说&#xff0c;目前&#xff0c;有几个好的细分领域值得我们去建立自己的技术壁垒&#x…

LLM 大模型框架 LangChain 可观测性最佳实践

LLM&#xff08;Large Language Model&#xff09;大模型的可观测性是指对模型内部运行过程的理解和监控能力。由于LLM大模型通常具有庞大的参数量和复杂的网络结构&#xff0c;因此对其内部状态和运行过程的理解和监控是一个重要的问题。 什么是 LangChain&#xff1f; Lang…

回溯算法02-组合总合III(Java)

2.组合总合III 题目描述 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k 3,…

simplex算法的代码实现

def pivot(N, B, A, b, c, v, l, e):N对应非基本元变量下标,B对应基本元变量下标,A对应非基本元在约束方程组中的系数相反数形成的矩阵,b对应约束条件中小于等于号右边的数值集合,c对应目标函数中变量系数形成的集合,v对应当前目标函数的取值,l对应转出变量下标在B中的位置&am…

nodejs版本管理工具nvm安装和环境变量配置

1、下载nvm.exe https://github.com/coreybutler/nvm-windows/releases2、安装 1.在D盘根目录新建一个dev文件夹&#xff0c;在dev里面再新建一个nodejs。 2.双击下载好的nvm.exe 修改文件路径&#xff0c;且路径中不能有中文 3.安装完成后在D:\dev\nvm打开settings.txt&…

C++写食堂菜品管理系统

说明:本博文来自CSDN-问答板块,题主提问。 需要:学校拟开发一套食堂菜品管理系统,以便对菜品和同学们的评价进行管理,其中包含如下信息: 商户:商户名称、柜面位置、电话…… 菜品:菜品编号、菜品名称、价格、所属商户…… 学生:注册账号、昵称、电话…… 食堂里的商户…