/** @file
* @brief 自动计算单通道图像二值化阈值
* @author ImageJ fh
* 由于VC编译器Max, Min函数可能会出现问题, 所以有关求最值函数全部自定义在cpp文件中
*/
#include "auto_thresholder.h"
/*****************************************常用函数*********************************************/
static int CalcMaxValue(int a, int b)
{
return (a > b) ? a : b;
}
static double CalcMaxValue(double a, double b)
{
return (a > b) ? a : b;
}
static int CalcMinValue(int a, int b)
{
return (a < b) ? a : b;
}
static double CalcMinValue(double a, double b)
{
return (a < b) ? a : b;
}
void AutoThresholder::CalcHist(const cv::Mat& src, std::vector<int>& data)
{
CV_Assert(CV_8UC1 == src.type());
data.clear();
// 初始化数组
const int GRAY_LEVEL = 256;
for (int i = 0; i < GRAY_LEVEL; ++i)
{
data.push_back(0);
}
// 统计每个灰度级及其对应的像素个数
for (int y = 0; y < src.rows; ++y)
{
for (int x = 0; x < src.cols; ++x)
{
int value = src.at<uchar>(y, x);
data.at(value) += 1;
}
}
}
int AutoThresholder::DefaultIsoData(const std::vector<int>& data)
{
// This is the modified IsoData method used by the "Threshold" widget in "Default" mode
int n = data.size();
std::vector<int> data2(n, 0);
int mode = 0, maxCount = 0;
for (int i = 0; i < n; i++)
{
int count = data[i];
data2[i] = data[i];
if (data2[i] > maxCount)
{
maxCount = data2[i];
mode = i;
}
}
int maxCount2 = 0;
for (int i = 0; i < n; i++)
{
if ((data2[i] > maxCount2) && (i != mode))
maxCount2 = data2[i];
}
int hmax = maxCount;
if ((hmax > (maxCount2 * 2)) && (maxCount2 != 0))
{
hmax = (int)(maxCount2 * 1.5);
data2[mode] = hmax;
}
return IJIsoData(data2);
}
int AutoThresholder::IJIsoData(std::vector<int>& data)
{
// This is the original ImageJ IsoData implementation, here for backward compatibility.
int level;
int maxValue = data.size() - 1;
double result, sum1, sum2, sum3, sum4;
int count0 = data[0];
data[0] = 0; //set to zero so erased areas aren't included
int countMax = data[maxValue];
data[maxValue] = 0;
int min = 0;
while ((data[min] == 0) && (min < maxValue))
min++;
int max = maxValue;
while ((data[max] == 0) && (max > 0))
max--;
if (min >= max)
{
data[0] = count0; data[maxValue] = countMax;
level = data.size() / 2;
return level;
}
int movingIndex = min;
int inc = CalcMaxValue(max / 40, 1);
do
{
sum1 = sum2 = sum3 = sum4 = 0.0;
for (int i = min; i <= movingIndex; i++)
{
sum1 += (double)i*data[i];
sum2 += data[i];
}
for (int i = (movingIndex + 1); i <= max; i++)
{
sum3 += (double)i*data[i];
sum4 += data[i];
}
result = (sum1 / sum2 + sum3 / sum4) / 2.0;
movingIndex++;
} while ((movingIndex + 1) <= result && movingIndex < max - 1);
data[0] = count0; data[maxValue] = countMax;
level = (int)std::round(result);
return level;
}
int AutoThresholder::Huang(const std::vector<int>& data)
{
const int GRAY_LEVELS = 256;
int threshold = -1;
int ih = 0;
int it = 0;
int first_bin = 0;
int last_bin = 0;
double sum_pix = 0.0;
double num_pix = 0.0;
double term = 0.0;
double ent = 0.0; // entropy
double min_ent = 0.0; // min entropy
double mu_x = 0.0;
/* Determine the first non-zero bin */
first_bin = 0;
for (ih = 0; ih < GRAY_LEVELS; ih++)
{
if (data[ih] != 0)
{
first_bin = ih;
break;
}
}
/* Determine the last non-zero bin */
last_bin = 255;
for (ih = 255; ih >= first_bin; ih--)
{
if (data[ih] != 0)
{
last_bin = ih;
break;
}
}
term = 1.0 / (double)(last_bin - first_bin);
std::vector<double> mu_0(GRAY_LEVELS, 0.0);
sum_pix = num_pix = 0;
for (ih = first_bin; ih < GRAY_LEVELS; ih++)
{
sum_pix += (double)ih * data[ih];
num_pix += data[ih];
/* NUM_PIX cannot be zero ! */
mu_0[ih] = sum_pix / num_pix;
}
//double[] mu_1 = new double[256];
std::vector<double> mu_1(GRAY_LEVELS, 0.0);
sum_pix = num_pix = 0;
for (ih = last_bin; ih > 0; ih--)
{
sum_pix += (double)ih * data[ih];
num_pix += data[ih];
/* NUM_PIX cannot be zero ! */
mu_1[ih - 1] = sum_pix / (double)num_pix;
}
/* Determine the threshold that minimizes the fuzzy entropy */
threshold = -1;
min_ent = DBL_MAX;
for (it = 0; it < GRAY_LEVELS; it++)
{
ent = 0.0;
for (ih = 0; ih <= it; ih++)
{
/* Equation (4) in Ref. 1 */
mu_x = 1.0 / (1.0 + term * std::abs(ih - mu_0[it]));
if (!((mu_x < 1e-06) || (mu_x > 0.999999)))
{
/* Equation (6) & (8) in Ref. 1 */
ent += data[ih] * (-mu_x * std::log(mu_x) - (1.0 - mu_x) * std::log(1.0 - mu_x));
}
}
for (ih = it + 1; ih < GRAY_LEVELS; ih++)
{
/* Equation (4) in Ref. 1 */
mu_x = 1.0 / (1.0 + term * std::abs(ih - mu_1[it]));
if (!((mu_x < 1e-06) || (mu_x > 0.999999)))
{
/* Equation (6) & (8) in Ref. 1 */
ent += data[ih] * (-mu_x * std::log(mu_x) - (1.0 - mu_x) * std::log(1.0 - mu_x));
}
}
/* No need to divide by NUM_ROWS * NUM_COLS * LOG(2) ! */
if (ent < min_ent)
{
min_ent = ent;
threshold = it;
}
}
return threshold;
}
static bool BimodalTest(std::vector<double>& y)
{
int len = y.size();
bool b = false;
int modes = 0;
for (int k = 1; k < len - 1; k++)
{
if (y[k - 1] < y[k] && y[k + 1] < y[k])
{
modes++;
if (modes > 2) return false;
}
}
if (modes == 2) b = true;
return b;
}
int AutoThresholder::Intermodes(const std::vector<int>& data)
{
int maxbin = -1;
for (int i = 0; i < data.size(); i++)
{
if (data[i] > 0) maxbin = i;
}
int minbin = -1;
for (int i = data.size() - 1; i >= 0; i--)
{
if (data[i] > 0) minbin = i;
}
int length = (maxbin - minbin) + 1;
std::vector<double> hist(data.size(), 0);
for (int i = minbin; i <= maxbin; i++)
{
hist[i - minbin] = data[i];
}
int iter = 0;
int threshold = -1;
while (!BimodalTest(hist))
{
//smooth with a 3 point running mean filter
double previous = 0;
double current = 0;
double next = hist[0];
for (int i = 0; i < length - 1; i++)
{
previous = current;
current = next;
next = hist[i + 1];
hist[i] = (previous + current + next) / 3;
}
hist[length - 1] = (current + next) / 3;
iter++;
if (iter > 10000)
{
threshold = -1;
return threshold;
}
}
// The threshold is the mean between the two peaks.
int tt = 0;
for (int i = 1; i < length - 1; i++)
{
if (hist[i - 1] < hist[i] && hist[i + 1] < hist[i])
{
tt += i;
}
}
threshold = (int)std::floor(tt / 2.0);
return threshold + minbin;
}
int AutoThresholder::IsoData(const std::vector<int>& data)
{
int i = 0;
int l = 0;
int totl = 0;
int g = 0;
double toth = 0.0;
double h = 0.0;
const int GRAY_LEVELS = 256;
for (i = 1; i < GRAY_LEVELS; i++)
{
if (data[i] > 0)
{
g = i + 1;
break;
}
}
while (true)
{
l = 0;
totl = 0;
for (i = 0; i < g; i++)
{
totl = totl + data[i];
l = l + (data[i] * i);
}
h = 0;
toth = 0;
for (i = g + 1; i < GRAY_LEVELS; i++)
{
toth += data[i];
h += ((double)data[i] * i);
}
if (totl > 0 && toth > 0)
{
l /= totl;
h /= toth;
if (g == (int)std::round((l + h) / 2.0))
break;
}
g++;
if (g > 254) return -1;
}
return g;
}
int AutoThresholder::Li(const std::vector<int>& data)
{
int threshold = 0;
double num_pixels = 0;
double sum_back = 0; /* sum of the background pixels at a given threshold */
double sum_obj = 0; /* sum of the object pixels at a given threshold */
double num_back = 0; /* number of background pixels at a given threshold */
double num_obj = 0; /* number of object pixels at a given threshold */
double old_thresh = 0;
double new_thresh = 0;
double mean_back = 0; /* mean of the background pixels at a given thre
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
基于ImageJ和OpenCv的16种自动二值化图像代码(C++) (559个子文件)
1-SRC.bmp 2.8MB
circle_fit.bmp 446KB
OpenCVModules-release.cmake 25KB
OpenCVModules-debug.cmake 24KB
OpenCVModules.cmake 14KB
OpenCVConfig.cmake 14KB
OpenCVConfig-version.cmake 433B
auto_thresholder.cpp 29KB
test_auto_thresholder.cpp 828B
main.cpp 224B
opencv_imgproc340d.dll 26.46MB
opencv_imgproc340.dll 19.16MB
opencv_ffmpeg340.dll 16.08MB
opencv_core340d.dll 11.75MB
opencv_dnn340d.dll 8.62MB
opencv_core340.dll 7.83MB
opencv_imgcodecs340d.dll 4.7MB
opencv_xfeatures2d340d.dll 3.86MB
opencv_tracking340d.dll 3.31MB
opencv_dnn340.dll 3.29MB
opencv_calib3d340d.dll 2.87MB
opencv_xfeatures2d340.dll 2.74MB
opencv_imgcodecs340.dll 2.44MB
opencv_ximgproc340d.dll 2.38MB
opencv_tracking340.dll 2.03MB
opencv_stitching340d.dll 1.98MB
opencv_features2d340d.dll 1.85MB
opencv_face340d.dll 1.54MB
opencv_calib3d340.dll 1.51MB
opencv_text340d.dll 1.41MB
opencv_rgbd340d.dll 1.38MB
opencv_photo340d.dll 1.35MB
opencv_ml340d.dll 1.32MB
opencv_objdetect340d.dll 1.25MB
opencv_datasets340d.dll 1.24MB
opencv_xphoto340d.dll 1.18MB
opencv_ximgproc340.dll 1.18MB
opencv_ccalib340d.dll 1.16MB
opencv_videostab340d.dll 1.13MB
opencv_flann340d.dll 1.12MB
opencv_aruco340d.dll 1.03MB
opencv_optflow340d.dll 1.03MB
opencv_surface_matching340d.dll 1MB
opencv_stitching340.dll 969KB
opencv_line_descriptor340d.dll 837KB
opencv_video340d.dll 814KB
opencv_photo340.dll 813KB
opencv_features2d340.dll 761KB
opencv_saliency340d.dll 696KB
opencv_face340.dll 675KB
opencv_ml340.dll 667KB
opencv_bgsegm340d.dll 638KB
opencv_shape340d.dll 636KB
opencv_rgbd340.dll 622KB
opencv_ccalib340.dll 617KB
opencv_videoio340d.dll 602KB
opencv_bioinspired340d.dll 589KB
opencv_text340.dll 587KB
opencv_videostab340.dll 576KB
opencv_structured_light340d.dll 566KB
opencv_superres340d.dll 560KB
opencv_datasets340.dll 558KB
opencv_stereo340d.dll 555KB
opencv_xphoto340.dll 554KB
opencv_xobjdetect340d.dll 545KB
opencv_dpm340d.dll 530KB
opencv_objdetect340.dll 520KB
opencv_reg340d.dll 492KB
opencv_aruco340.dll 491KB
opencv_optflow340.dll 473KB
opencv_video340.dll 427KB
opencv_img_hash340d.dll 424KB
opencv_flann340.dll 417KB
opencv_highgui340d.dll 407KB
opencv_phase_unwrapping340d.dll 394KB
opencv_surface_matching340.dll 386KB
opencv_fuzzy340d.dll 383KB
opencv_plot340d.dll 320KB
opencv_bgsegm340.dll 305KB
opencv_bioinspired340.dll 298KB
opencv_line_descriptor340.dll 288KB
opencv_shape340.dll 287KB
opencv_saliency340.dll 277KB
opencv_superres340.dll 275KB
opencv_stereo340.dll 272KB
opencv_structured_light340.dll 249KB
opencv_videoio340.dll 245KB
opencv_reg340.dll 217KB
opencv_xobjdetect340.dll 209KB
opencv_dpm340.dll 204KB
opencv_img_hash340.dll 194KB
opencv_fuzzy340.dll 186KB
opencv_highgui340.dll 177KB
opencv_phase_unwrapping340.dll 149KB
opencv_plot340.dll 136KB
opencv_traincascaded.exe 809KB
opencv_interactive-calibrationd.exe 422KB
opencv_traincascade.exe 316KB
opencv_annotationd.exe 182KB
opencv_visualisationd.exe 182KB
共 559 条
- 1
- 2
- 3
- 4
- 5
- 6
资源评论
- qq_299251332022-03-11666,稳的一批
- shijig20052020-07-14里面就一个基于OpenCV开发的auto_thresholder其它什么都没有,和ImageJ没有任何关系。57MB大小其实都是openCV开发包wfh20152020-09-29你这是在抬杠?ImageJ里面那些自动化阈值算法已经经过修改后放到auto_thresholder里面,怎么就和ImageJ没关系?不然你还想怎样?opencv开发包可以让小白用vs2015打开就能运行,你不爽可以不下载!
- iori888888882018-10-11厉害厉害厉害厉害厉害wfh20152020-10-06哈哈 兄弟 你是认真看过代码的 有个二货啥等没仔细看就自以为是的给了个一颗星差评
wfh2015
- 粉丝: 48
- 资源: 95
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功