图像处理之一维熵阈值分割

上篇是关于OTSU,与本文的一维熵阈值分割十分相似,只是这里用到了熵函数
比较简不做详细讲述,代码如下

#include <iostream>
#include <opencv2/opencv.hpp>
#include <Eigen/Dense>
#include <math.h>
#include <stack>
#define _MATH_DEFINES_DEFINED
using namespace std;
using namespace cv;
using namespace Eigen;
float Otsu(const Mat& image, int T)
{
	int nr = image.rows;
	int nl = image.cols;
	Mat hist = Mat::zeros(1, 256, CV_32F);
	float* hi = hist.ptr<float>(0);
	float h1 = 0;//类一的熵
	float h2 = 0;//类二的熵
	float pt = 0;//类一的概率
	float pg = 0;//总熵
	for (int i = 0; i < nr; i++)
	{
		const float* im = image.ptr<float>(i);
		for (int j = 0; j < nl; j++)
		{
			hi[int(im[j])] = hi[int(im[j])] + 1;
		}
	}
	//cout << hist << endl;
	for (int i = 0; i <=T; i++)
	{
		pt = pt + hi[i] / nr / nl;
	}
	for (int i = 0; i <= T; i++)
	{
		float ppp = log10f(hi[i] / nr / nl / pt);
		if(hi[i] / nr / nl / pt<0.00001)
		{ }
		else h1 = h1 - hi[i] / nr / nl / pt * log10f(hi[i] / nr / nl / pt);
	}
	for (int i = T + 1; i < 256; i++)
	{
		if (hi[i] / nr / nl / (1-pt) < 0.00001)
		{
		}
		else h2 = h2 - hi[i] / nr / nl / (1 - pt) * log10f(hi[i] / nr / nl / (1 - pt));
	}
	pg = h1 + h2;
	return pg;
}
int getT(const Mat& image, Mat& new_image)
{
	int temp = 0;
	float max = 0;
	max = Otsu(image, 40);
	for (int i = 40; i < 240; i++)//寻找最大的分割点
	{
		float gg = Otsu(image, i);
		if (max < gg)
		{
			temp = i;
			max = gg;
		}
	}
	for (int i = 0; i < image.rows; i++)//二值化
	{
		const float* im = image.ptr<float>(i);
		float* p = new_image.ptr<float>(i);
		for (int j = 0; j < image.cols; j++)
		{
			float ge = im[j];
			if (ge <= temp)
			{
				p[j] = 0;
			}
			else
			{
				p[j] = 255;
			}

		}
	}
	return temp;
}
int main()
{
	Mat image = imread("I:/C.jpg", IMREAD_GRAYSCALE);
	imshow("原图像", image);
	Mat IM;
	image.convertTo(IM, CV_32F);
	//imshow("fsSSd", IM);
	Mat new_image = Mat::zeros(IM.rows, IM.cols, CV_32F);
	int T = getT(IM, new_image);
	cout << T << endl;
	imshow("新图像", new_image);
	cv::waitKey(0);
}

结果如下
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值