zoukankan      html  css  js  c++  java
  • 3.6.1最大熵阈值分割寻找阈值实现图像二值化

     1 #include <opencv2/imgproc/imgproc.hpp>
     2 #include <opencv2/core/core.hpp>
     3 #include <opencv2/highgui/highgui.hpp>
     4 #include <iostream>
     5 
     6 using namespace cv;
     7 using namespace std;
     8 
     9 //按给定的threshold,计算hist的背景熵和目标熵的总和
    10 float caculateCurrentEntropy(Mat hist, int threshold)
    11 {
    12     float BackgroundSum = 0, targetSum = 0;
    13     const float* pDataHist = (float*)hist.ptr<float>(0);
    14     for (int i = 0; i < 256; i++)
    15     {
    16         //累计背景值
    17         if (i < threshold)
    18         {
    19             BackgroundSum += pDataHist[i];
    20         }
    21         //累计目标值
    22         else
    23         {
    24             targetSum += pDataHist[i];
    25         }
    26     }
    27     cout << BackgroundSum << "	" << targetSum << endl;
    28     float BackgroundEntropy = 0, targetEntropy = 0;
    29     for (int i = 0; i < 256; i++)
    30     {
    31         //计算背景熵
    32         if (i < threshold)
    33         {
    34             if (pDataHist[i] == 0)
    35                 continue;
    36             float ratio1 = pDataHist[i] / BackgroundSum;
    37             //计算当前能量熵
    38             BackgroundEntropy += -ratio1*logf(ratio1);
    39         }
    40         else  //计算目标熵
    41         {
    42             if (pDataHist[i] == 0)
    43                 continue;
    44             float ratio2 = pDataHist[i] / targetSum;
    45             targetEntropy += -ratio2*logf(ratio2);
    46         }
    47     }
    48     return (targetEntropy + BackgroundEntropy);
    49 }
    50 //寻找最大熵阈值并分割,根据该阈值进行二值化
    51 Mat maxEntropySegMentation(Mat inputImage)
    52 {
    53     const int channels[1] = { 0 };
    54     const int histSize[1] = { 256 };
    55     float pranges[2] = { 0,256 };
    56     const float* ranges[1] = { pranges };
    57     MatND hist;
    58     calcHist(&inputImage, 1, channels, Mat(), hist, 1, histSize, ranges);
    59     float maxentropy = 0;
    60     int max_index = 0;
    61     Mat result;
    62     for (int i = 0; i < 256; i++)
    63     {
    64         float cur_entropy = caculateCurrentEntropy(hist, i);
    65         if (cur_entropy > maxentropy)
    66         {
    67             maxentropy = cur_entropy;
    68             max_index = i;
    69         }
    70     }
    71     threshold(inputImage, result, max_index, 255, CV_THRESH_BINARY);
    72     return result;
    73 }
    74 int main()
    75 {
    76     Mat srcImage = imread("D:\hand.jpg");
    77     if (!srcImage.data)
    78         return -1;
    79     Mat grayImage;
    80     cvtColor(srcImage, grayImage, CV_BGR2GRAY);
    81     Mat result = maxEntropySegMentation(grayImage);
    82     imshow("grayImage", grayImage);
    83     imshow("result", result);
    84     waitKey(0);
    85     return 0;
    86 }
    View Code

     运行效果:

  • 相关阅读:
    高并发核心技术
    2年java,蚂蚁一面,卒
    Spring Boot 实战 入门
    spring-boot-plus后台快速开发脚手架之代码生成器使用
    spring-boot-plus后台快速开发框架1.0.0.RELEASE发布了
    spring-boot-plus后台快速开发框架1.0.0.RELEASE发布了
    Spring Boot项目使用maven-assembly-plugin根据不同环境打包成tar.gz或者zip
    从尾到头打印单向链表
    单向链表操作
    合并两个排序的数组
  • 原文地址:https://www.cnblogs.com/thebreakofdawn/p/9430349.html
Copyright © 2011-2022 走看看