今天复习Otsu算法,它利用阈值奖图片转成黑白色。Otsu算法是二值算法,目的是求出一个Threshhold,来最小化Within-Class方差,这等价最大化between-class方差。下面用java来实现算法。

package com.lili.ots<pre name="code" class="java">package com.lili.otsu;
public class OtsuThresholder
{private int histData[];private int maxLevelValue;private int threshold;public OtsuThresholder(){histData = new int[256];}public int[] getHistData(){return histData;}public int getMaxLevelValue(){return maxLevelValue;}public int getThreshold(){return threshold;}public int doThreshold(byte[] srcData, byte[] monoData){int ptr;// Clear histogram data// Set all values to zeroptr = 0;while (ptr < histData.length) histData[ptr++] = 0;// Calculate histogram and find the level with the max value// Note: the max level value isn't required by the Otsu methodptr = 0;maxLevelValue = 0;while (ptr < srcData.length){int h = 0xFF & srcData[ptr];  histData[h] ++;if (histData[h] > maxLevelValue) maxLevelValue = histData[h];ptr ++;}// Total number of pixelsint total = srcData.length;                //48*57 image, total=48*57float sum = 0;for (int t=0 ; t<256 ; t++) sum += t * histData[t];float sumB = 0;int wB = 0;int wF = 0;float varMax = 0;threshold = 0;for (int t=0 ; t<256 ; t++){wB += histData[t];                 // Weight Background if (wB == 0) continue;   // 'cause divide           the number of pixle of backgroundwF = total - wB;                      // Weight Foregroundif (wF == 0) break;                sumB += (float) (t * histData[t]);float mB = sumB / wB;             // Mean Backgroundfloat mF = (sum - sumB) / wF;        // Mean Foreground// Calculate Between Class Variancefloat varBetween = (float)wB * (float)wF * (mB - mF) * (mB - mF); // Check if new maximum foundif (varBetween > varMax) {varMax = varBetween;threshold = t;}}// Apply threshold to create binary imageif (monoData != null){ptr = 0;while (ptr < srcData.length)            // 48*57{monoData[ptr] = ((0xFF & srcData[ptr]) >= threshold) ? (byte) 255 : 0;ptr ++;}}return threshold;}
}
package com.lili.otsu;import java.io.*;import java.util.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;import com.lili.otsu.GreyFrame;
import com.lili.otsu.OtsuThresholder;public class OtsuDemo
{public OtsuDemo(String filename){// Load Source imageBufferedImage srcImage = null;try{File imgFile = new File(filename);srcImage = javax.imageio.ImageIO.read(imgFile);}catch (IOException ioE){System.err.println(ioE);System.exit(1);}int width = srcImage.getWidth();int height = srcImage.getHeight();// Get raw image dataRaster raster = srcImage.getData();DataBuffer buffer = raster.getDataBuffer();int type = buffer.getDataType();if (type != DataBuffer.TYPE_BYTE){System.err.println("Wrong image data type");System.exit(1);}if (buffer.getNumBanks() != 1){System.err.println("Wrong image data format");System.exit(1);}DataBufferByte byteBuffer = (DataBufferByte) buffer;byte[] srcData = byteBuffer.getData(0);// Sanity check imageif (width * height  != srcData.length) {System.err.println("Unexpected image data size. Should be greyscale image");System.exit(1);}// Output Image infoSystem.out.printf("Loaded image: '%s', width: %d, height: %d, num bytes: %d\n", filename, width, height, srcData.length);byte[] dstData = new byte[srcData.length];// Create Otsu ThresholderOtsuThresholder thresholder = new OtsuThresholder();int threshold = thresholder.doThreshold(srcData, dstData);System.out.printf("Threshold: %d\n", threshold);// Create GUIGreyFrame srcFrame = new GreyFrame(width, height, srcData);GreyFrame dstFrame = new GreyFrame(width, height, dstData);GreyFrame histFrame = createHistogramFrame(thresholder);JPanel infoPanel = new JPanel();infoPanel.add(histFrame);JPanel panel = new JPanel(new BorderLayout(5, 5));panel.setBorder(new javax.swing.border.EmptyBorder(5, 5, 5, 5));panel.add(infoPanel, BorderLayout.NORTH);panel.add(srcFrame, BorderLayout.WEST);panel.add(dstFrame, BorderLayout.EAST);panel.add(new JLabel("QingrouShui", JLabel.CENTER), BorderLayout.SOUTH);JFrame frame = new JFrame("QingrouShui");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.getContentPane().add(panel);frame.pack();frame.setVisible(true);// Save Imagestry{int dotPos = filename.lastIndexOf(".");String basename = filename.substring(0,dotPos);javax.imageio.ImageIO.write(dstFrame.getBufferImage(), "PNG", new File(basename+"_BW.png"));javax.imageio.ImageIO.write(histFrame.getBufferImage(), "PNG", new File(basename+"_hist.png"));}catch (IOException ioE){System.err.println("Could not write image " + filename);}}private GreyFrame createHistogramFrame(OtsuThresholder thresholder){int numPixels = 256 * 100;byte[] histPlotData = new byte[numPixels];int[] histData = thresholder.getHistData();int max = thresholder.getMaxLevelValue();int threshold = thresholder.getThreshold();for (int l=0 ; l<256 ; l++){int ptr = (numPixels - 256) + l;int val = (100 * histData[l]) / max;if (l == threshold){for (int i=0 ; i<100 ; i++, ptr-=256) histPlotData[ptr] = (byte) 128;}else{for (int i=0 ; i<100 ; i++, ptr-=256) histPlotData[ptr] = (val < i) ? (byte) 255 : 0;}}return new GreyFrame(256, 100, histPlotData);}public static void main(String args[]){new OtsuDemo("lili_icmv12.png");System.out.println("QingrouShui");
//      if (args.length<1) {
//          System.err.println("Provide image filename");
//          System.exit(1);
//      }}
}
<pre name="code" class="java">package com.lili.otsu;
import java.awt.*;import javax.swing.*;
import java.awt.image.*;
import java.awt.color.*;public class GreyFrame extends JComponent
{private int width;private int height;private Dimension size;private BufferedImage image;private String title;public GreyFrame(int width, int height, byte[] data){this(width, height, data, null);}public GreyFrame(int width, int height, byte[] data, String title){this.width = width;this.height = height;this.title = title;size = new Dimension(width, height);DataBufferByte dataBuffer = new DataBufferByte(data, data.length, 0);PixelInterleavedSampleModel sampleModel = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, width, height, 1, width, new int[] {0});ColorSpace colourSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);ComponentColorModel colourModel = new ComponentColorModel(colourSpace, new int[] {8}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);WritableRaster raster = Raster.createWritableRaster(sampleModel, dataBuffer, null);image = new BufferedImage(colourModel, raster, false, null);}public Graphics2D getBufferImageGraphics(){return image.createGraphics();}public BufferedImage getBufferImage(){return image;}public Dimension getSize(){return size;}public Dimension getPreferredSize(){return size;}public void paint(Graphics g){super.paint(g);if (image != null) g.drawImage(image, 0, 0, this);if (title != null) {g.setColor(Color.RED);g.drawString(title, 5, height - 5);}}
}

<img src="https://img-blog.csdn.net/20150401123028357" alt="" /><img src="https://img-blog.csdn.net/20150401123001341" alt="" />

Otsu Thresholding相关推荐

  1. C#,图像二值化(06)——全局阈值的大津算法(OTSU Thresholding)及其源代码

    1.大津算法OTSU ALGORITHM OTSU算法效果很一般. 最大类间方差法是1979年由日本学者大津(Nobuyuki Otsu)提出的,是一种自适应阈值确定的方法,又叫大津法,简称OTSU, ...

  2. Image Thresholding

    摘自https://docs.opencv.org/4.2.0/d7/d4d/tutorial_py_thresholding.html Simple Thresholding The functio ...

  3. 训练过程出现trian_dice一直大于1(mask范围0-255转为0-1)

    文章目录 0. 背景知识 0.1 mask 0.2 SimpleITK快速入门 1. 使用Threshold类方法 1.1 sitk.RescaleIntensityImageFilter 1.1.1 ...

  4. python 椭圆检测_使用OpenCV和Python检测触摸/重叠圆/椭圆

    这是我检测圈子的尝试.综上所述 >执行BGR-> HSV转换,并使用V通道进行处理 V通道: >阈值,应用形态关闭,然后进行距离转换(我会称之为dist) 分区形象: >创建一 ...

  5. SimpleITK笔记本中ITK细分(Segmentation)介绍

    SimpleITK笔记本中ITK细分(Segmentation)介绍 目标:熟悉ITK中可用的基本分割算法,并以交互方式探索其参数空间. 图像分割滤波器处理图像,将其分割成(希望)有意义的区域.输出通 ...

  6. AnswerOpenCV(0826-0901)一周佳作欣赏

    1.OpenCV to detect how missing tooth in equipment Hello everyone. I am just starting with OpenCV and ...

  7. (病理图像质控)分割病理图像(whole slide images,WSI)中包含组织的区域,去掉空白区域

    文末有代码链接!!!!! 修改 2023-03-14 偷空写个帖子. 在处理全病理切片(WSI)的时候,经常会碰到一个问题.就是整个WSI很大,其中有很多空白的地方,深度学习或者传统的图像处理都不需要 ...

  8. 图像处理之二值化图像

    图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果.将所有灰度大于或等于阈值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以 ...

  9. 人工智能——图像处理和Python深度学习的全教程(建议收藏)

    介绍 在这篇文章中,我们将学习如何执行图像处理.在整篇文章中,我们使用到的库是Scikit Image. 基础知识 1.什么是图像? 图像数据可能是文本之后最常见的数据.那么,电脑如何理解你在埃菲尔铁 ...

最新文章

  1. build怎么调试 react_webpack打包调试react并使用babel编译jsx配置方法
  2. 同余方程———扩展欧几里得
  3. cortex系列处理器排行_ARM推出Cortex-A78C处理器,欲夺X86笔记本市场
  4. Android 4 学习(19):Services
  5. tdbgrid 数据类型输入错误 vb_VB语言基础(上)
  6. tensorflow 显存 训练_Tensorflow与Keras自适应使用显存方式
  7. Dvsdk 下的CMEM学习
  8. Windows服务器配置DFS实现文件同步
  9. 将图像数据jpg,png等存储为npy/npz格式
  10. Windows 10系统下Outlook日历怎么显示农历?
  11. 微信公众平台移动版开始内测了
  12. Swift:一个简单的货币转换器App在iOS10中的分析和完善
  13. npm 包解析 eml 文件
  14. 使用maya.cmds加载和卸载插件
  15. sql语句查询一天24小时每个小时数据,查询时间段内每天数据
  16. 利用Python实现NBA球员分析绘制数据可视化图表
  17. 网罗软件测试知识体系汇总
  18. Kerberos在linux安装部署
  19. apple pay集成_如何将Google Pay集成到您现有的Android应用中
  20. wine常见问题集合

热门文章

  1. 电子表设计与验证(时钟频率选择)
  2. 一文读懂数据库发展史
  3. Is the server running on host 192.168.121.128 and accepting TCP/IP connections on port 5432?
  4. 记一次GenerationTarget encountered exception accepting command : Error executing DDL的解决技巧
  5. BG2RHE - 用AtmelStudio7给ATMEGA芯片下载Arduino的bootloader的简便方法
  6. vue cli4 vue2 多页面打包配置与坑点
  7. 程序员的十年黄金时期,你是否有机会抓住?
  8. 三维标量场绘图MATLAB,基于MATLAB的地学可视化实现
  9. springboot毕设项目山东魏桥创业集团有限公司外贸出口管理信息系统fyndb(java+VUE+Mybatis+Maven+Mysql)
  10. 算法:通过普利姆(Prim)算法,求出图的最小生成树