当前位置: 首页 > news >正文

cv::阈值分割OTUS原理+代码

opencv库的阈值分割分为全局分割和局部分割

全局分割:普通分割

ret1,th1 = cv2.threshold(img,127, 255, cv2.THRESH_BINARY)
#127为阈值
#cv2.THRESH_BINARY |cv2.THRESH_BINARY_INV | cv2.THRESH_TRUNC|cv2.THRESH_TOZERO|cv2.THRESH_TOZERO_INV

局部分割:自适应分割,阈值自计算

th2=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)
#阈值变为
#均值:cv2.ADAPTIVE_THRESH_MEAN_C,
#高斯加权:cv2.ADAPTIVE_THRESH_GAUSSIAN_C
#窗口大小:11
#c:均值-常数

特殊:OTUS 大津法,最大类间方差

ret2,th2 = cv2.threshold(img,0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

原理:

使用于双峰图像,将灰度直方图分为两部分,使得两部分类间方差最大,试了一下两部分类内方差最小也行,效果差不多,opencv的api用的是最大类间方差.

步骤:

  1. 灰度图片计算灰度直方图,并归一化

  1. 类间方差计算:其实就是求灰度的方差

  1. 假设当前灰度阈值为i,将[0,256]分为h1=[0,i-1]和h2=[i,256]两部分

  1. 求每一部分的灰度个数s = sum(h[i]),求s1,s2

  1. 求每一部分的灰度均值,mean = sum(h1[i]*i)/s求m1,m2,mg(总积分)

  1. 求每一个类间的方差,[s1*(m1-mg)*(m1-mg)+s2*(m2-mg)*(m2-mg)]/(s1+s2)

d.(1),类内方差v = sum((i-m)*(i-m)*h[i]/s),最小类内方差也行

  1. i 取值[0,256],求使得类间方差最大的i就是阈值

import cv2
import numpy as np
import matplotlib.pyplot as pltimg = cv2.imread("otsu.jpg",0)hist = cv2.calcHist([img],[0],None,[256],[0,256])
histnorm = (hist-hist.min())/(hist.max()-hist.min())
bins = np.arange(256)# plt.plot(histnorm)
# plt.xlim([0,256])
# plt.show()fnmin = 99999
tmp = 0
fnmax = 0
tm = 0
p = hist/sum(hist)
histnorm = np.squeeze(histnorm)
for i in range(1,256):s1 = np.sum(histnorm[:i])s2 = np.sum(histnorm[i:])q1 = histnorm[i:]*bins[i:]m1 = np.sum(histnorm[:i] * bins[:i])/s1m2 = np.sum(histnorm[i:] * bins[i:])/s2mg = np.sum(histnorm* bins)/(s1+s2)#最大类间方差fm = (s1*(m1-mg)*(m1-mg)+ s2*(m2-mg)*(m2-mg))/(s1+s2)if fm>fnmax:fnmax = fmtm = i#最小类内方差v1 = np.sum((bins[:i] - m1)*(bins[:i] - m1)*(histnorm[:i])/s1)v2 = np.sum((bins[i:] - m2)*(bins[i:] - m2)*(histnorm[i:])/s2)fn = v1+v2if fn<fnmin:fnmin = fntmp = iret1,th1 = cv2.threshold(img,tm, 255, cv2.THRESH_BINARY)
print(tm,ret1)
ret2,th2 = cv2.threshold(img,tmp, 255, cv2.THRESH_BINARY)
print(tmp,ret2)
ret3,th3 = cv2.threshold(img,0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print(ret3)cv2.imshow("th1",th1)
cv2.imshow("th2",th2)
cv2.imshow("th3",th3)
cv2.waitKey(0)

图片:从别博客里面保存的

结果:最大类间方差和cv2.THRESH_OTSU计算出来的阈值一样,最小类间方差要小一点

http://www.lryc.cn/news/37659.html

相关文章:

  • Postgresql-12.5 visual studio-2022 windows 添加pg工程并调试
  • 长沙学院2023 第一次蓝桥训练题解
  • 云端Docker搭建ABY库以及本地CLion使用
  • ES6-箭头函数、解构赋值、对象简写
  • 【CSS】CSS 背景设置 ② ( 背景位置 | 背景位置-方位值设置 )
  • HTML 扫盲
  • 项目中用到的责任链模式
  • C++复习笔记--STL的string容器和vector容器
  • 第一章 软件项目管理概述
  • 【Linux系统编程】06:共享内存
  • 【专项】112. 路径总和
  • 【数据结构】堆排序
  • 论文阅读笔记《GAMnet: Robust Feature Matching via Graph Adversarial-Matching Network》
  • 数据安全—数据完整性校验
  • Java 最小路径和
  • Flask+VUE前后端分离的登入注册系统实现
  • 【Go】用Go在命令行输出好看的表格
  • 怎么处理消息重发的问题?
  • JVM 运行时数据区(数据区组成表述,程序计数器,java虚拟机栈,本地方法栈)
  • Oracle ASM磁盘组配置、日常运维、故障处理等操作资料汇总
  • java对象的创建与内存分配机制
  • 本地存储localStorage、sessionStorage
  • JavaSE: 网络编程
  • 计算机图形学09:二维观察之点的裁剪
  • 2023Java 并发编程面试题
  • CAD如何绘制A0/A1/A2/A3/A4图框?
  • R 安装 “umap-learn“ python 包
  • 测试同学如何快速开发测试平台?
  • 【程序员接口百宝箱】免费常用API接口
  • 使数组和能被P整除[同余定理+同余定理变形]