Python与FPGA——全局二值化

文章目录

  • 前言
  • 一、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.shapepdict = {}for i in range(h):for j in range(w):if image[i,j] in pdict:pdict[image[i,j]] += 1else:pdict[image[i,j]] = 0return pdict"""
求公式4中sigma2的值
T0: 预设阈值(int)
gray: 灰度图(ndarray)
L: 灰度等级(int)
"""
def sigma2(T0, gray, L=256):h, w = gray.shapeN = h * wpdict = pixel_num(gray)pf = sum([v for k,v in pdict.items() if k < T0]) / N#公式1pb = sum([v for k,v in pdict.items() if k >= T0]) / N#公式1pf = [pf if pf > 1e-6 else 1e-6][0]#控制最小值,避免除以0pb = [pb if pb > 1e-6 else 1e-6][0]#控制最小值,避免除以0mf = sum([k * pdict.get(k, 0) / N for k in range(T0)]) / pf#公式2mb = sum([k * pdict.get(k, 0) / N for k in range(T0, L)]) / pb#公式2M = pf * mf + pb * mb#公式3s2 = pf * (mf - M) ** 2 + pb * (mb - M) ** 2#公式4return s2, T0"""
遍历查找最大sigma2
gray: 灰度图(ndarray)
L: 灰度等级(int)
"""
def otsu(gray, L=256):smax = 0tmax = 0for t in range(1, L):s2, T0 = sigma2(t, gray, L)if s2 > smax:smax = s2tmax = T0return 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 binarysmax, 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;elsey_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]};elsebinary_data <= binary_data;
endmodule

在这里插入图片描述


总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

el-table 插入单选并进行校验

<template><div><el-form :model"list" ref"ruleForm"><el-table :data"list.tableData" style"width: 100%"><el-table-column prop"time" label"日期" width"180"><…

SpringBoot初步学习

SpringBoot 今日目标&#xff1a; 掌握基于SpringBoot框架的程序开发步骤 熟练使用SpringBoot配置信息修改服务器配置 基于SpringBoot的完成SSM整合项目开发 1. SpringBoot简介 SpringBoot 其设计目的是用来简化 Spring 应用的初始搭建以及开发过程。 1.1 SpringBoot快速…

nodejs web服务器 之初始化路由

每当一个请求到达服务器之后&#xff0c;需要先经过路由的匹配&#xff0c;只有匹配成功之后&#xff0c;才会调用对应的处理函数。在匹配时&#xff0c;会按照顺序进行匹配&#xff0c;请求类型和请求的URL同时匹配成功&#xff0c;返回对应的数据。 我们可以创建一个js文件&a…

万马合一之js解答

输入m和n 两个数&#xff0c;m和n表示一个mn 的棋盘。输入棋盘内的数据。棋盘中存在数字和".“两种字符&#xff0c;如果是数字表示Q该位置是一匹马&#xff0c;如果是”."表示该位置为空的&#xff0c;棋盘内的数字表示为该马能走的最大步数。例如棋盘内某个位置一个…

【notepad++工具使用之】批量加逗号

背景 在使用sql语句in关键字查询时&#xff0c;我们需要把数据用逗号进行隔开&#xff0c;在数据量非常少的时候&#xff08;十几二十个这样&#xff09;&#xff0c;可以手动的去加逗号分隔符&#xff1b; 但是遇到1000个怎么弄呢&#xff1f; 强大的Notepad 批量处理数据时…

【中间件】docker的安装

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;中间件 ⛺️稳中求进&#xff0c;晒太阳 .卸载旧版 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \doc…

指针的学习4

目录 回调函数 qsort使用样例 使用qsort函数排序整形数据 使用qsort函数排序结构体 回调函数 回调函数就是一个通过函数指针调用的函数。如果把函数的指针&#xff08;地址&#xff09;作为参数传递给另一个函数&#xff0c;当这个指针被用来调用其所指向的函数时&#xf…

【MetaGPT】多智能体协作——你画我猜(文字版)

多智能体协作 本篇将学习 MetaGPT中的 Environment 、 Team 组件。 1. Muti Agent 概念概述 多智能体系统 (Multi-Agent System, MAS) 是由一群具有一定自主性、协同性和学习能力的智能体组成的系统。智能体在环境中相互协作&#xff0c;以达到某种目标或完成特定任务。 2. 多…

利用websocket +定时器简易的实现一个网络聊天室

其实原理非常简单,就是客户端用户通过websoket来连接websocket服务端。然后服务端,收集每个用户发出的消息, 进而将每条用户的消息通过广播的形式推送到每个连接到服务端的客户端。从而实现用户的实时聊天。 // TODO : 我主要是讲一下实现思路。并未完善其功能。 1.后端 依赖 …

【UE 材质 Niagara】爆炸效果

目录 效果 步骤 一、材质部分 二、Niagara部分 效果 步骤 一、材质部分 1. 创建一个材质&#xff0c;这里命名为“M_Burst” 打开“M_Burst”&#xff0c;设置混合模式为半透明&#xff0c;设置着色模型为无光照&#xff0c;勾选双面显示 在材质图表中首先创建扰动效果 其…

「Mybatis深入五」:动态SQL

文章目录 一、应用场景二、代码演示1、动态 **SQL** 之\<if>&#xff08;1&#xff09; 需求&#xff08;2&#xff09;代码 2、动态 **SQL** 之\<choose>&#xff08;1&#xff09; 需求&#xff08;2&#xff09;代码 3、动态 **SQL** 之\<set>&#xff08…

Google如何快速抓接口导入到postman调试

Google如何快速抓接口导入到postman调试 1、F12选择对应接口&#xff0c;右键后复制接口连接信息 2、打开postman&#xff0c;点击import 3、在raw text都粘贴 4、点击continue后&#xff0c;导入就可以了