我想實現多級大津的閾值,更具體地說,我需要3個閾值/ 4類。多級(4)Otsu閾值
我知道關於它的2個similair問題:#34856019和#22706742。 問題是我沒有得到好的結果:我閱讀了幾篇文章,其中的代碼圖片和代碼發現的閾值與這些論文中的不同。
比方說,我有一個黑色背景上的3個圈圖片,圓圈的亮度從非常明亮的不同而不同暗:
我說得對的假設得到的結果是4班級:黑色背景和3個班級的強度?
我的節目給了我這些閾值:226,178,68
其結果是,第三圈是完全看不見的 - 這是在同一個班作爲背景。
有人可以檢查這些值和/或源代碼嗎?也許有可能使用Matlab或其他方式檢查此圖像... 順便說一句,通過零處理分割的最佳方法是什麼?這種方法通常在直方圖中出現零值? 源代碼:
void MultilevelThresholding(cv::Mat& src)
{
int histogram[256] = { 0 };
int pixelsCount = src.cols * src.rows;
for (int y = 0; y < src.rows; y++)
{
for (int x = 0; x < src.cols; x++)
{
uchar value = src.at<uchar>(y, x);
histogram[value]++;
}
}
double c = 0;
double Mt = 0;
double p[256] = { 0 };
for (int i = 0; i < 256; i++)
{
p[i] = (double) histogram[i]/(double) pixelsCount;
Mt += i * p[i];
}
int optimalTreshold1 = 0;
int optimalTreshold2 = 0;
int optimalTreshold3 = 0;
double maxBetweenVar = 0;
double w0 = 0;
double m0 = 0;
double c0 = 0;
double p0 = 0;
double w1 = 0;
double m1 = 0;
double c1 = 0;
double p1 = 0;
double w2 = 0;
double m2 = 0;
double c2 = 0;
double p2 = 0;
for (int tr1 = 0; tr1 < 256; tr1++)
{
p0 += p[tr1];
w0 += (tr1 * p[tr1]);
if (p0 != 0)
{
m0 = w0/p0;
}
c0 = p0 * (m0 - Mt) * (m0 - Mt);
c1 = 0;
w1 = 0;
m1 = 0;
p1 = 0;
for (int tr2 = tr1 + 1; tr2 < 256; tr2++)
{
p1 += p[tr2];
w1 += (tr2 * p[tr2]);
if (p1 != 0)
{
m1 = w1/p1;
}
c1 = p1 * (m1 - Mt) * (m1 - Mt);
c2 = 0;
w2 = 0;
m2 = 0;
p2 = 0;
for (int tr3 = tr2 + 1; tr3 < 256; tr3++)
{
p2 += p[tr3];
w2 += (tr3 * p[tr3]);
if (p2 != 0)
{
m2 = w2/p2;
}
c2 = p2 * (m2 - Mt) * (m2 - Mt);
c = c0 + c1 + c2;
if (maxBetweenVar < c)
{
maxBetweenVar = c;
optimalTreshold1 = tr1;
optimalTreshold2 = tr2;
optimalTreshold3 = tr3;
}
}
}
}
添加一個大的中值濾波器來消除邊緣處的衰落效應?你是否嘗試k-means聚類(4簇)而不是otsu? – Micka
是的,我可以添加任何我想要的過濾器,但這只是一個例子 - 問題是關於Otsu及其閾值。你認爲這樣做對嗎? – natan337
我不知道,但它看起來像你的代碼只承擔3閾值(optimalThreshold1-3)而不是4? – Micka