OSTU定点化

278人阅读 评论(0)

#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
typedef long long ll;
typedef long long tp;
int postu(IplImage *src); //定点化，没考虑图像大小，没有对变量范围考虑，统一使用long long格式
int ddostuBigImage(IplImage *src);//图像大小为1000*1000以上时使用
int ddostuSmallImage(IplImage *src);//图像大小为100*100以下时使用

#include "stdafx.h"
#include "dingdian.h"
int ddostuSmallImage(IplImage *src)
{
int height=src->height;
int width=src->width;
uchar histogram[256]={0};
uchar * p;
for ( int i=0; i<height; ++i )
{
p=(unsigned char*)src->imageData + src->widthStep * i;
for ( int j=0; j<width; ++j )
{
histogram[*p++]++;
}
}

short size = height * width;
int avgValue = 0;
for(int i=0; i < 256; i++)
{
avgValue += i * histogram[i];  //整幅图像的平均灰度
}
int threshold=0;
int maxVariance = 0;
int w = 0;
int u = 0;

for(int i = 0; i < 256; i++)
{
w += histogram[i];  //假设当前灰度i为阈值, 0~i 灰度的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例
u += i * histogram[i];  // 灰度i 之前的像素(0~i)的平均灰度值： 前景像素的平均灰度值
unsigned short t = avgValue * w/size - u;
unsigned short variance = (t * t)/((long long)w*(size-w)+1);
if(variance > maxVariance)
{
maxVariance = variance;
threshold = i;
}
}
return threshold;
}
int ddostuBigImage(IplImage *src)
{
int height=src->height;
int width=src->width;
short histogram[256]={0};
uchar * p;
for ( int i=0; i<height; ++i )
{
p=(unsigned char*)src->imageData + src->widthStep * i;
for ( int j=0; j<width; ++j )
{
histogram[*p++]++;
}
}

int size = height * width;
int avgValue = 0;
for(int i=0; i < 256; i++)
{
avgValue += i * histogram[i];  //整幅图像的平均灰度
}

int threshold=0;
int maxVariance = 0;
int w = 0;
int u = 0;
for(int i = 0; i < 256; i++)
{
w += histogram[i];  //假设当前灰度i为阈值, 0~i 灰度的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例
u += i * histogram[i];  // 灰度i 之前的像素(0~i)的平均灰度值： 前景像素的平均灰度值
long long t = (long long)avgValue * w/size - u;
int variance = (t * t)/((long long)w*(size-w)+1);
//cout<<variance<<" ";
if(variance > maxVariance)
{
maxVariance = variance;
threshold = i;
}
//cout<<threshold<<" ";
}
return threshold;
}
int postu(IplImage *src)
{
int height=src->height;
int width=src->width;

//histogram
long histogram[256] = {0};
unsigned char* p;
for(int i=0; i < height; i++)
{
p=(unsigned char*)src->imageData + src->widthStep * i;
for(int j = 0; j < width; j++)
{
histogram[*p++]++;
}
}

//normalize histogram
tp size = height * width;

/*	for(int i = 0; i < 256; i++)
{
histogram[i] = histogram[i] / size;
} */

//average pixel value
tp avgValue = 0;
for(int i=0; i < 256; i++)
{
avgValue += i * histogram[i];  //整幅图像的平均灰度
}
int threshold=0;
tp maxVariance = 0;
tp w = 0, u = 0;
for(int i = 0; i < 256; i++)
{
w += histogram[i];  //假设当前灰度i为阈值, 0~i 灰度的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例
u += i * histogram[i];  // 灰度i 之前的像素(0~i)的平均灰度值： 前景像素的平均灰度值
tp t = avgValue * w/size - u;
//float  variance = (t * t) / (float)(w * (size - w));
tp variance = (t * t)/(w*(size-w)+1);
//cout<<variance<<endl;
//system("pause");
//float variance = (t*t*size*size)/(w*(size-w)*size)+0.5;
if(variance > maxVariance)
{
maxVariance = variance;
threshold = i;
}
//cout<<threshold<<" ";
}
return threshold;
}

<pre class="cpp" name="code">// opencv300.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/videoio/videoio.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>
#include <cctype>
using namespace cv;
using namespace std;
#include "dingdian.h"

int Otsu(IplImage* src)
{
int height=src->height;
int width=src->width;

//histogram
float histogram[256] = {0};
unsigned char* p;
for(int i=0; i < height; i++)
{
p=(unsigned char*)src->imageData + src->widthStep * i;
for(int j = 0; j < width; j++)
{
histogram[*p++]++;
}
}
//normalize histogram
int size = height * width;
for(int i = 0; i < 256; i++)
{
histogram[i] = histogram[i] / size;
}

//average pixel value
float avgValue=0;
for(int i=0; i < 256; i++)
{
avgValue += i * histogram[i];  //整幅图像的平均灰度
}

int threshold;
float maxVariance=0;
float w = 0, u = 0;
for(int i = 0; i < 256; i++)
{
w += histogram[i];  //假设当前灰度i为阈值, 0~i 灰度的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例
u += i * histogram[i];  // 灰度i 之前的像素(0~i)的平均灰度值： 前景像素的平均灰度值

float t = avgValue * w - u;
/*cout<<t*size<<endl;
cout<<w*size<<endl;
system("pause");*/
float variance = t * t / (w * (1 - w)+0.00001);
//float variance = (t*t*size*size)/(w*(size-w)*size)+0.5;
if(variance > maxVariance)
{
maxVariance = variance;
threshold = i;
}
//cout<<variance<<" ";
//system("pause");
}
return threshold;
}

int main(int argc, const char ** argv)
{
double t = (double)getTickCount();
int thres = Otsu(&IplImage(img));
t = ((double)getTickCount() - t)*1000/getTickFrequency();
cout<<thres<<endl;
cout<<"浮点 "<<t<<endl;

t = (double)getTickCount();
int thres2 = postu(&IplImage(img));
t = ((double)getTickCount() - t)*1000/getTickFrequency();
cout<<thres2<<endl;
cout<<"修改 "<<t<<endl;

t = (double)getTickCount();
int thres3 = ddostuBigImage(&IplImage(img));
t = ((double)getTickCount() - t)*1000/getTickFrequency();
cout<<thres3<<endl;
cout<<"大图 "<<t<<endl;

t = (double)getTickCount();
int thres4 = ddostuSmallImage(&IplImage(img));
t = ((double)getTickCount() - t)*1000/getTickFrequency();
cout<<thres4<<endl;
cout<<"小图 "<<t<<endl;

int thres1 = Uotsu(uimg);
cout<<thres1<<endl;*/
cin>>thres;
//int thres=Otsu(&IplImage(binaryImage))+10;
//threshold(binaryImage,binaryImage,thres,255,1);

}


0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：7189次
• 积分：263
• 等级：
• 排名：千里之外
• 原创：16篇
• 转载：6篇
• 译文：0篇
• 评论：2条
文章分类
最新评论