当前位置: 首页 > 编程日记 > 正文

前景背景分割——ostu算法的原理及实现 OpenCV (八)

OpenCV 【八】——前景背景分割——ostu算法的原理及实现

        • 实验结果
        • 代码实现
        • 实现原理
        • 参考资料

实验结果

在这里插入图片描述

代码实现

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
//计算图像灰度直方图
Mat calcgrayhist(const Mat& image)
{Mat histogram = Mat::zeros(Size(256, 1), CV_32SC1);//图像宽高int rows = image.rows;int cols = image.cols;for (int i = 0; i < rows; i++){for (int j = 0; j < rows; j++){int index = int(image.at<uchar>(i, j));histogram.at<int>(0, index) += 1;}}return histogram;
};//OTSU
int OTSU(const Mat& image, Mat& OTSU_image)
{int rows = image.rows;int cols = image.cols;Mat histogram = calcgrayhist(image);//归一化直方图Mat normhist;histogram.convertTo(normhist, CV_32FC1, 1.0 / (rows * cols), 0.0);//计算累加直方图和一阶累积矩Mat zeroaccumulate = Mat::zeros(Size(256, 1), CV_32FC1);Mat oneaccumulate = Mat::zeros(Size(256, 1), CV_32FC1);for (int i = 0; i < 256; i++){if (i == 0){zeroaccumulate.at<float>(0, i) = normhist.at<float>(0, i);oneaccumulate.at<float>(0, i) = i * normhist.at<float>(0, i);}else{zeroaccumulate.at<float>(0, i) = zeroaccumulate.at<float>(0, i - 1)+ normhist.at<float>(0, i);oneaccumulate.at<float>(0, i) = oneaccumulate.at<float>(0, i - 1)+ i * normhist.at<float>(0, i);}}//计算间类方差Mat variance = Mat::zeros(Size(256, 1), CV_32FC1);float mean = oneaccumulate.at<float>(0, 255);for (int i = 0; i < 255; i++){if (zeroaccumulate.at<float>(0, i) == 0 || zeroaccumulate.at<float>(0, i) == 1)variance.at<float>(0, i) = 0;else{float cofficient = zeroaccumulate.at<float>(0, i) * (1.0 -zeroaccumulate.at<float>(0, i));variance.at<float>(0, i) = pow(mean * zeroaccumulate.at<float>(0, i)- oneaccumulate.at<float>(0, i), 2.0) / cofficient;}}//找到阈值;Point maxloc;//计算矩阵中最大值minMaxLoc(variance, NULL, NULL, NULL, &maxloc);int otsuthreshold = maxloc.x;threshold(image, OTSU_image, otsuthreshold, 255, THRESH_BINARY);return otsuthreshold;
};int main()
{Mat img, gray_img, dst;img = imread("E:\\workspace\\opencv_study\\example\\1.jpg");imshow("img", img);cvtColor(img, gray_img, COLOR_BGR2GRAY);imwrite("1_gray.bmp", gray_img);imshow("gray_img", gray_img);OTSU(gray_img, dst);imshow("otsu image", dst);imwrite("ostu.bmp", dst);waitKey(0);return 0;
};

实现原理

Otsu算法(大津法或最大类间方差法)使用的是聚类的思想,把图像的灰度数按灰度级分成2个部分使得两个部分之间的灰度值差异最大,每个部分之间的灰度差异最小,通过方差的计算来寻找一个合适的灰度级别来划分。 所以可以在二值化的时候采用otsu算法来自动选取阈值进行二值化。otsu算法被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响。因此,使类间方差最大的分割意味着错分概率最小

从L个灰度级遍历t,使得t为某个值的时候,前景和背景的方差最大, 则 这个 t 值便是我们要求得的阈值。

其中,方差的计算公式如下:
g=wo * (uo - u) * (uo - u) + w1 * (u1 - u) * (u1 - u)

[ 此公式计算量较大,可以采用:
g = wo * w1 * (uo - u1) * (uo - u1) ]
在这里插入图片描述

//实现方法1:
Source Code: https://blog.csdn.net/silent_gods/article/details/81046919
//将OTSU算法实现了一遍#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"#include <string>
#include <stdio.h>using namespace std;
using namespace cv;//#define Gamma 3//OTSU 函数实现
int OTSU(Mat srcImage) 
{int nCols = srcImage.cols;int nRows = srcImage.rows;int threshold = 0;//init the parametersint nSumPix[256];float nProDis[256];for (int i = 0; i < 256; i++){nSumPix[i] = 0;nProDis[i] = 0;}//统计灰度集中每个像素在整幅图像中的个数for (int i = 0; i < nRows; i++){for (int j = 0; j < nCols; j++){nSumPix[(int)srcImage.at<uchar>(i, j)]++;}}//计算每个灰度级占图像中的概率分布for (int i = 0; i < 256; i++){nProDis[i] = (float)nSumPix[i] / (nCols*nRows);}//遍历灰度级【0,255】,计算出最大类间方差下的阈值float w0, w1, u0_temp, u1_temp, u0, u1, delta_temp;double delta_max = 0.0;for (int i = 0; i < 256; i++){//初始化相关参数w0 = w1 = u0 = u1 = u0_temp = u1_temp = delta_temp = 0;for (int j = 0; j < 256; j++){//背景部分if (j <= i){w0 += nProDis[j];u0_temp += j*nProDis[j];}//前景部分else{w1 += nProDis[j];u1_temp += j*nProDis[j];}}//计算两个分类的平均灰度u0 = u0_temp / w0;u1 = u1_temp / w1;//依次找到最大类间方差下的阈值delta_temp = (float)(w0*w1*pow((u0 - u1), 2)); //前景与背景之间的方差(类间方差)if (delta_temp > delta_max){delta_max = delta_temp;threshold = i;}}return threshold;
}int  main()
{namedWindow("srcGray", 0);cvResizeWindow("srcGray", 640, 480);namedWindow("otsuResultImage", 0);cvResizeWindow("otsuResultImage", 640, 480);namedWindow("dst", 0);cvResizeWindow("dst", 640, 480);//图像读取及判断Mat srcImage;srcImage = imread("D:\\0604.png");if (!srcImage.data){return -1;}imshow("srcImage", srcImage);Mat srcGray;cvtColor(srcImage, srcGray, CV_RGB2GRAY);imshow("srcGray", srcGray);//调用otsu算法得到图像int otsuThreshold = OTSU(srcGray);cout << otsuThreshold << endl;//定义输出结果图像Mat otsuResultImage = Mat::zeros(srcGray.rows, srcGray.cols, CV_8UC1);//利用得到的阈值进行二值化操作for (int i = 0; i < srcGray.rows; i++){for (int j = 0; j < srcGray.cols; j++){//cout << (int)srcGray.at<uchar>(i, j) << endl;//高像素阈值判断if (srcGray.at<uchar>(i, j) > otsuThreshold){otsuResultImage.at<uchar>(i, j) = 255;}else{otsuResultImage.at<uchar>(i, j) = 0;}//cout <<(int)otsuResultImage.at<uchar>(i, j) << endl;}}imshow("otsuResultImage", otsuResultImage);waitKey(0);return 0;
}

参考资料

https://www.cnblogs.com/moon1992/p/5092726.html
https://blog.csdn.net/silent_gods/article/details/81046919
https://blog.csdn.net/u012005313/article/details/51945075
https://blog.csdn.net/liuzhuomei0911/article/details/51440305
https://blog.csdn.net/xiachong27/article/details/80572469
https://blog.csdn.net/u011574296/article/details/72829925
https://baike.baidu.com/item/otsu/16252828?fr=aladdin
https://www.cnblogs.com/uestc-mm/p/5366908.html
https://blog.csdn.net/baimafujinji/article/details/50629103

相关文章:

【PAT (Basic Level) 】1015 德才论 (25 分)

宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”&#xff1a;“是故才德全尽谓之圣人&#xff0c;才德兼亡谓之愚人&#xff0c;德胜才谓之君子&#xff0c;才胜德谓之小人。凡取人之术&#xff0c;苟不得圣人&#xff0c;君子而与之&#xff0c;与其得小人&#xff0…

浏览器启动外部软件

常可以看见使用浏览器代码启动本地应用的软件.例如qq、迅雷、等等.那么他们是怎么做到的呢? 它的奥秘:Register protocol 前言我们经常看到 tencent://..thunder://这两种开头的网址&#xff0c;往往觉得很奇怪&#xff0c;很想弄懂其中的原理&#xff0c;是如何实现的&#x…

Luogu P1082 同余方程(NOIP 2012) 题解报告

题目传送门 【题目大意】 求关于x的同余方程 ax≡1(mod b)的最小整数解。 【思路分析】 由同余方程的有关知识可得&#xff0c;ax≡1(mod b)可以化为axby1&#xff0c;此方程有解当且仅当gcd(a,b)1&#xff0c;于是就可以用欧几里得算法求出一组特解x0&#xff0c;y0。 那么x0就…

MATLAB【二】————图像做减法,批量文本处理,子图显示

clear; clc; close all;name_string ["1.5ms\100\" ];length strlength(name_string); [m,n] size(length);%%----------------------------- for num1:mstr name_string(num,1); figure(color, [1, 1, 1], position, [0, 0, 1800,800]); % 为区分边界&a…

与数据有关的问题

&#xfeff;&#xfeff;◆ 背景说明 在为用户排查问题&#xff0c;解决问题时&#xff0c;有一种情况是不容易引起大家注意的&#xff0c;那就是用户的数据&#xff1b;比如&#xff0c;数据中有某些特殊字符&#xff0c;引起展现不了或展现不正常&#xff1b;现在&#xff…

【PAT (Basic Level) 】1024 科学计数法 (20 分)

科学计数法是科学家用来表示很大或很小的数字的一种方便的方法&#xff0c;其满足正则表达式 [][1-9].[0-9]E[][0-9]&#xff0c;即数字的整数部分只有 1 位&#xff0c;小数部分至少有 1 位&#xff0c;该数字及其指数部分的正负号即使对正数也必定明确给出。 现以科学计数法…

jsp 实栗 jsp + jdbc 登录

jsp 实栗 jsp jdbc 实现登录 实现思路 一个表单页&#xff0c;输入用户登录和密码&#xff0c;然后信息提交到jsp页面进行验证&#xff0c;如果可以服务器跳转到登录成功页&#xff0c;失败&#xff0c;跳转到错误页 跳转的时候窗口的URL地址会发生变化 代码如下 编写登录代码…

OpenCV 【十】——Gamma校正 ——图像灰度变化

Gamma校正&#xff08;C、OpenCV实现&#xff09; 1.作用&#xff1a; Gamma校正是对输入图像灰度值进行的非线性操作&#xff0c;使输出图像灰度值与输入图像灰度值呈指数关系&#xff1a; 伽玛校正由以下幂律表达式定义&#xff1a; 2.函数原型 void calcHist( const Mat*…

Linux磁盘阵列技术详解(二)--raid 1创建

我在Linux磁盘阵列技术详解&#xff08;一&#xff09;里已经详细介绍了几种RAID磁盘阵列方式&#xff0c;原理以及创建raid 0 的详细步骤。那么这篇文档就着重讲解如何创建raid 1的技术&#xff1a;步骤如下&#xff1a;① 分区同样我们还是以一块硬盘的不同分区为例&#xff…

【PAT (Basic Level) 】1025 反转链表 (25 分)

给定一个常数 K 以及一个单链表 L&#xff0c;请编写程序将 L 中每 K 个结点反转。例如&#xff1a;给定 L 为 1→2→3→4→5→6&#xff0c;K 为 3&#xff0c;则输出应该为 3→2→1→6→5→4&#xff1b;如果 K 为 4&#xff0c;则输出应该为 4→3→2→1→5→6&#xff0c;即…

C#关于窗体的传值

关于窗体之间的传值我在《编程技巧与维护》杂志上写过总结文章&#xff0c;比较久远了。 开始的时候&#xff0c;用下面的方法传递&#xff0c;程序运行正常。 Form1 f1 this.Owner as Form1; //Form1 f1 (Form1)this.Owner;&#xff08;这样写也可以&#xff09; …

MATLAB【四】 ————批量适配图片信息与excel/txt等文档信息,批量移动拷贝图片,批量存图片中点和方框

1、批量读取图片&#xff0c;批量读取文件 2、适配文件与excel、txt等文档信息 3、获取显示图片ROI、Point、rect、更改像素值 4、批量移动拷贝图片&#xff0c;批量显示 5、保存显示图片或者图片中的点和方框。 clear; clc; close all;%% crop the im into 256*256 num 0…

mysql日志文件相关的配置【2】

1、二进制日志是什么&#xff1f; mysql 的二进制日志用于记录数据库上做的变更、 2、二进制日志什么时间写到磁盘 1、总的来说二进制日志会在释放锁之前就写入磁盘、也就是说在commit完成之前&#xff1b;client还没发送commit这个时候mysql并不把binlog写入磁盘、 别一方面my…

【PAT (Basic Level) 】1028 人口普查 (20 分)

某城镇进行人口普查&#xff0c;得到了全体居民的生日。现请你写个程序&#xff0c;找出镇上最年长和最年轻的人。这里确保每个输入的日期都是合法的&#xff0c;但不一定是合理的——假设已知镇上没有超过 200 岁的老人&#xff0c;而今天是 2014 年 9 月 6 日&#xff0c;所以…

SW6206超级华为快充5V5A,全协议OPPO闪充、自带电量计量、LED 灯/数码管显示

深圳市展嵘电子有限公司有需要的上帝可联系小陈&#xff1a;136-6225-3950 : 3412-1522-98SW6206 是一款高集成度的多协议双向快充移动电源专用多合一芯片&#xff0c;支持AABCL 口任意口快充。其集成了5A高效率开关充电&#xff0c;20W高效率同步升压输出&#xff0c;PPS/PD/Q…

bash脚本【一】——批量处理文件

Bash脚本2.0 #!/bin/bashoutput_root_dir"0723weixin" data_root_dir"D:/data/"$output_root_dir config_dir"config"# speckle_name"SPEACKLEIMAGE.bmp" # ir_name"IRIMAGE.bmp" # rgb_name"RGBIMAGE.jpg" # co…

【PAT (Basic Level) 】1030 完美数列 (25 分)

给定一个正整数数列&#xff0c;和正整数 p&#xff0c;设这个数列中的最大值是 M&#xff0c;最小值是 m&#xff0c;如果 M≤mp&#xff0c;则称这个数列是完美数列。 现在给定参数 p 和一些正整数&#xff0c;请你从中选择尽可能多的数构成一个完美数列。 【输入格式】&…

运营商劫持处理

测试URL&#xff1a;因近期发现长宽资源经常出现被劫持和转发错误的现象。解决办法如下&#xff1a;1、把转发列表写到named.conf文件里&#xff0c;更新我们的转发ip2、然后编写策略针对我们要去的域名从BGP出口出去&#xff0c;防止NAT。x.x.x.x.com&#xff0c;&#xff08;…

oracle维护数据的完整性

转自&#xff1a;https://www.cnblogs.com/roger112/p/7722376.html 介绍&#xff1a; 数据的完整性用于确保数据库数据遵从一定的商业的逻辑规则。在oracle中&#xff0c;数据完整性可以使用约束、触发器、应用程序(过程、函数)三种方法来实现&#xff0c;在这三种方法中&…

MATLAB【五】———— matlab 调用C++生成exe文件,高斯核函数

两种方式调用C生成的exe文件&#xff0c; 语法&#xff1a; status system(command) [status,cmdout] system(command) [status,cmdout] system(command,-echo) 说明 status system(command) 调用操作系统执行指定的命令。操作会等待命令执行完毕&#xff0c;然后再将命令…

REACT day 1

https://facebook.github.io/react/ A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES Declarative views make your code more predictable and easier to debug. React是Facebook在2013年发布的一个前端框架&#xff0c;而如今的React俨然已经演变成一个前端生态&#xff…

win10+Chrome浏览器截长图方法

本方法亲测可行&#xff0c;操作系统为win10&#xff0c;其他操作系统没有试过。 部分内容基于https://blog.csdn.net/ianly123/article/details/80565614并进行修正。 打开 Chrome 浏览器&#xff0c;进入需要截图的网站页面。打开开发者工具&#xff1a;在页面任何地方点击…

如何打造一流的视觉AI技术

本次分享主要分以下几个部分&#xff1a;首先简要介绍一下计算机视觉技术的相关背景&#xff0c;然后结合格灵深瞳的实践&#xff0c;从算法研发、训练平台、智能数据处理、异构计算等几个方面着重介绍如何打造一流的视觉AI技术&#xff0c;最后介绍格灵深瞳在相关技术落地方面…

MATLAB【六】 ———— matlab 随机散斑模拟

%% %input for image size(NX,NY) <散斑图大小&#xff08;像素&#xff09;> NX 1280; NY 800; %input for numble of speckles(S)<散斑数量> S 9226; %输入的散斑大小 a 4; %input for peak intensity of each speckle(I0)<散斑峰值强度> I0 1; %input …

【Python】zip函数

zip()函数用于将可迭代对象作为参数&#xff0c;将对象中对应的元素打包成一个个元组&#xff0c;然后返回这些由元组组成的列表。 如果各个迭代器的元素不一致&#xff0c;则返回列表长度与最短的对象相同。 利用*号操作符&#xff0c;可将元组解压为列表。 >>> a …

CentOS 7.0,启用iptables防火墙

CentOS 7.0默认使用的是firewall作为防火墙&#xff0c;这里改为iptables防火墙。1、关闭firewall&#xff1a;systemctl stop firewalld.service #停止firewallsystemctl disable firewalld.service #禁止firewall开机启动2、安装iptables防火墙yum install iptables-services…

手撸 webpack4.x 配置(一)

现在的前端开发框架 &#xff0c;都绕不开 webpack 打包 。 但绝大数前端开发人员 基本都是用 脚手架 自动生成 一套开发环境 如&#xff1a; vue-cli , create-react-app等 , 但开发中总会遇到各种问题 &#xff0c;基本都是 webpack 配置问题 &#xff0c; 每次遇到基本都是…

MATLAB【七】———— matlab 高斯核使用,超像素图像模拟,矩阵转图像,深度相机模型实践实现

深度模型&#xff0c;图片转稀疏矩阵&#xff0c;稀疏矩阵转图片 %% mat to 2array temp_speckle ref_speckle; [row_index,col_index,v]find(temp_speckle); obj_matrix [row_index,col_index]; [obj_matrix_height,obj_matrix_width] size(obj_matrix);%% depth camera m…

jsp 出现cannot be resolved to a type问题解决办法

&#xff08;1&#xff09;检查<% page import>是否导入了相关的包。若是没有则需导入 &#xff08;2&#xff09;若导入相应的包后问题仍然存在则需创建相关的servlet转载于:https://www.cnblogs.com/wth21-1314/p/6126655.html

U盘中毒了?教你如何删除System Volume Information这个顽固文件夹

不得不说cmd命令很好用呢。最近我的U盘中毒了&#xff0c;格式化都删除不了System Volume Information这个顽固的文件夹&#xff0c;真心伤不起哇&#xff01;还好现在解决了问题。看来以后得好好对待U盘&#xff0c;不能乱用了。本篇文章教大家如何删除System Volume Informat…