1. 程式人生 > >基於OpenCV和C++實現最大閾值分割演算法

基於OpenCV和C++實現最大閾值分割演算法

程式碼如下::

/**********************************************************************************************************
*檔案說明:
*        基於OpenCv的閾值分割演算法
*開發環境:
*        win7+vs2010+opencv2.4.8
*時間地點:
*        陝西師範大學.2017.2。19
*作    者:
*        李麗 
***********************************************************************************************************/
#include<opencv2/opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
#include "cv.h"
#include "highgui.h"
#include <iostream> 
using namespace std;
using namespace cv;

/***********************************************************************************************************
   巨集定義
***********************************************************************************************************/
int HistogramBins = 256;
float HistogramRange1[2] = {0,255};
float *HistogramRange[1] = {&HistogramRange1[0]};
typedef enum {back,object} entropy_state;

/***********************************************************************************************************
   // 計算當前位置的閾值
***********************************************************************************************************/
double caculateCurrentEntropy(CvHistogram * Histogram1, int cur_threshold, entropy_state state)
{
	int i,start,end;
	if(state == back)     
	{
	  start = 0;
	  end = cur_threshold; 
	}
	else
	{
	  start = cur_threshold;
	  end = 256;
	}
	int  total = 0;
	for(int i = start; i < end; i++) 
	{
	  total += (int)cvQueryHistValue_1D(Histogram1, i);  //cvQueryHistValue_1D()函式是訪問直方圖的方式
	}
	double cur_entropy = 0.0;
	for(i = start; i < end; i++)
	{
	  if((int)cvQueryHistValue_1D(Histogram1,i) == 0)
	   continue;
	  float percentage = cvQueryHistValue_1D(Histogram1, i) / total;
	  cur_entropy += - percentage * logf(percentage); // 能量的定義公式
	}
	return cur_entropy;
}

/***********************************************************************************************************
   // 尋找最大熵閾值並分割
***********************************************************************************************************/

void MaxEntropy(IplImage *src, IplImage *dst)
{
	
	CvHistogram * hist  = cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY, HistogramRange);   //OpenCV中直方圖的  CvHistogram資料型別的理解

	cvCalcHist(&src, hist);				//建立直方圖
	double maxentropy = -1.0;          ////???
	int max_index = -1;					////???
	// 迴圈測試每個分割點,尋找到最大的閾值分割點
	for(int i = 0; i < HistogramBins; i++)     // int HistogramBins = 256;
	{
	  double cur_entropy = caculateCurrentEntropy(hist, i, object) + caculateCurrentEntropy(hist, i, back);
	  if(cur_entropy > maxentropy)
	  {
	   maxentropy = cur_entropy;
	   max_index = i;
	  }
	}
	cvThreshold(src, dst, (double)max_index, 255, CV_THRESH_BINARY);
	cvReleaseHist(&hist);
}

/***********************************************************************************************************
   // 主函式   控制檯應用程式入口  
***********************************************************************************************************/
int main()
{
	IplImage* src = cvLoadImage("G:\\C++Study\\Demo\\MaxETG\\MaxETG\\lena.png",CV_LOAD_IMAGE_GRAYSCALE );   //CV_LOAD_IMAGE_GRAYSCALE   
	cvNamedWindow("Image", 1); 
	cvNamedWindow("origin", 1);

	IplImage* dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
	
	MaxEntropy(src, dst);     //關鍵函式呼叫---求最大熵閾值分割結果
	
	cvShowImage("Image", dst); // 顯示影象
	cvShowImage("origin", src);
	
	cvWaitKey(0);             // 等待按鍵
	cvDestroyWindow("Image"); // 銷燬視窗
	cvDestroyWindow("origin");
	cvReleaseImage(&src);     // 釋放影象
	cvReleaseImage(&dst);
	
	return 0;
	}


執行結果如下:  左邊為原始影象   右邊為最大熵閾值分割函式處理之後的函式


相關推薦

基於OpenCVC++實現分割演算法

程式碼如下:: /********************************************************************************************************** *檔案說明: * 基於Ope

opencv——分割

opencv1.0版本 #include "stdio.h" #include "cv.h" #include "highgui.h" #include "Math.h" int Otsu(IplImage* src); int main(in

OpenCV程式設計:分割演算法實現(程式碼可執行)

        將資訊理論中的 shannon 熵概念用於影象分割, 其依據是使得影象中目標與背景分佈的資訊量最大,即通過測量影象灰度直方圖的熵,找出最佳閾值。根據 shannon 熵的概念,對於灰度範圍為 0,1,2,…,L-1 的影象,其直方圖的熵定義為(僅僅是定義)

使用OpenCVC++實現的分水嶺演算法(Watershed)

分水嶺演算法(watershed)是一種比較基本的數學形態學分割演算法,其基本思想是將灰度影象轉換為梯度影象,將梯度值看作高低起伏的山嶺,將區域性極小值及其鄰域看作一個“集水盆”。設想一個個“集水盆”中存在積水,且水位不斷升高,淹沒梯度較低的地方,當水漫過程停止後,影象就可

影象分割:1.基於的影象分割方法(分割法)

 利用影象熵為準則進行影象分割有一定歷史了,學者們提出了許多以影象熵為基礎進行影象分割的方法。我們介紹一種由Kapuret al提出來,現在仍然使用較廣的一種影象熵分割方法。 給定一個特定的閾值q(0<=q<K-1),對於該閾值所分割的兩個影象區域C0,C1,其估

分割演算法

#include <opencv2\opencv.hpp> #include <opencv\cv.h> using namespace cv; int HistogramBins = 256; float HistogramRange1[2

OTSU分割演算法原理與原始碼

OTSU閾值分割 OTSU閾值處理(最大類間方差),演算法步驟如下: 【1】統計灰度級中每個畫素在整幅影象中的個數。 【2】計算每個畫素在整幅影象的概率分佈。 【3】對灰度級進行遍歷搜尋,計算當前灰度值下前景背景類間概率。 【4】通過目標函式計算出類內與類間方差下對應的閾值

簡單的排序算法(CC++實現

最簡單的排序算法(C和C++實現)1、算法思想如下圖:把待排序的數都存在對應的數組的下標中,如果待排序的數有重復的,就用對應的數組加一,最後把數組的下標打印出來即可。2、源碼(C)如下:#include <stdio.h>int main (void){ int a[100], i, j,

LeetCode- 16. 接近的三數之和 (Medium)pythonc++實現

給定一個包括 n 個整數的陣列 nums 和 一個目標值 target。找出 nums 中的三個整數,使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。 例如,給定陣列 n

C問題

問題: Write a program that reads in five integers and then determines and prints the largest and the smallest integers in the group. #include

matlab基於遺傳演算法法的雙影象分割

利用最佳直方圖熵法(KSW熵法)及傳統遺傳演算法實現灰度影象二閾值分割 matlab程式碼如下: 1、main.m(主函式): %%%利用最佳直方圖熵法(KSW熵法)及傳統遺傳演算法實現灰度影象二閾值分割 %%%主程式 %% 初始部分,讀取影象及計算

【FIF_Bro的部落格】C++ 的最大優點是,它是一門強大,兼顧了底層效率的,高階語言。這使得 C++ 幾乎沒有任何侷限性,無所不能。只要你是一個追求極致達到偏執的人,你幾乎總可以追尋到它的影子存在。這門語言超高的開發成本,使得只有偏執的人,才會對它痴狂

C++ 的最大優點是,它是一門強大,兼顧了底層效率的,高階語言。這使得 C++ 幾乎沒有任何侷限性,無所不能。只要你是一個追求極致達到偏執的人,你幾乎總可以追尋到它的影子和存在。這門語言超高的開發成本...

影象卷積操作的手動實現基於opencvC++編譯環境)

        opencv環境下有自帶的filter2D()函式可以實現影象的卷積,自己寫一個卷積函式函式貌似是沒事找事。。。。好吧,事實是這是我們計算機視覺課程上的一項作業。我們很多演算法過程僅僅只呼叫別人寫好的介面,即使原理我們已經清楚,但是真正編寫程式碼的時候很多細節

C++ 關於連續子序列()問題

/* 江偉浚 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17458 Accept

學習筆記——c語言實現連續子序列之和的演算法

今天到圖書館借了本資料結構的書,翻開一看,原來這裡有我之前參加的周立功機試的題目,哎,真是後悔莫及啊!現在把這個問題好好總結一下,以備不時之需。 最大連續子序列之和問題:給出N個整數(可以為負)A1,A2,A3,…,An,找出i到j項之和的最大值,如果所有整數為負,最大值為

C++實現大堆小堆

堆 堆資料結構是一種陣列物件,它可以被視為一顆完全二叉樹結構(或者也有可能是滿二叉樹) 最大堆: 任一結點的關鍵碼均大於等於它的左右孩子的關鍵碼,其中堆頂的元素最大。(任一路徑中的元素升序排列) 最小堆: 任一結點的關鍵碼均小於等於它的左右

C++實現長公共子序列長公共子串

// LCS.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <string> #include <vector> #include <iostream> using

42.C#--集合的使用,創建一個集合,裏面添加一些數字,求平均值與,以及

一個 void n) write 賦值 += 最大 tel count static void Main(string[] args){//42.集合的使用,創建一個集合,裏面添加一些數字,求平均值與和,以及最大值,最小值//創建一個集合ArrayList list = n

線性代數-矩陣-加減 CC++實現

for 通過 turn oba c語言 bsp operator column name 原理解析: (此處補圖) 本節編寫矩陣的加法和減法,兩個矩陣相加,即把兩個相同大小的矩陣對應的元素分別相加 。兩個矩陣相減,把兩個相同大小矩陣的對應元素分別相減。 C++語言: 矩

【左神算法課】子數組小於某,求滿足條件的子數組個數

isempty all turn main .com color 子數組 sys ems 題目描述:    解法思路:   本題其實是滑動窗口的變形。主體思路為:   1.從第一個元素開始依次向後遍歷,同時維護兩個窗口(由於要同時操作窗口的頭部和尾部,故采用雙端隊