gpt4 book ai didi

opencv - 多 otsu(多阈值)与 openCV

转载 作者:太空宇宙 更新时间:2023-11-03 20:40:10 25 4
gpt4 key购买 nike

我正在尝试使用 otsu 进行多阈值处理。我目前使用的方法实际上是通过最大化类间方差,我已经设法获得与 OpenCV 库给出的阈值相同的阈值。然而,这只是通过运行一次 otsu 方法。

关于如何进行多级阈值处理或递归阈值处理的文档相当有限。获得大津原值后去哪里?希望得到一些提示,我一直在研究代码,添加一个外部 for 循环,但对于任何给定图像,下一个计算值始终是 254:(

如果需要,我的代码是:

//compute histogram first
cv::Mat imageh; //image edited to grayscale for histogram purpose
//imageh=image; //to delete and uncomment below;
cv::cvtColor(image, imageh, CV_BGR2GRAY);

int histSize[1] = {256}; // number of bins
float hranges[2] = {0.0, 256.0}; // min andax pixel value
const float* ranges[1] = {hranges};
int channels[1] = {0}; // only 1 channel used

cv::MatND hist;
// Compute histogram
calcHist(&imageh, 1, channels, cv::Mat(), hist, 1, histSize, ranges);

IplImage* im = new IplImage(imageh);//assign the image to an IplImage pointer
IplImage* finalIm = cvCreateImage(cvSize(im->width, im->height), IPL_DEPTH_8U, 1);
double otsuThreshold= cvThreshold(im, finalIm, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU );

cout<<"opencv otsu gives "<<otsuThreshold<<endl;

int totalNumberOfPixels= imageh.total();
cout<<"total number of Pixels is " <<totalNumberOfPixels<< endl;


float sum = 0;
for (int t=0 ; t<256 ; t++)
{
sum += t * hist.at<float>(t);
}
cout<<"sum is "<<sum<<endl;

float sumB = 0; //sum of background
int wB = 0; // weight of background
int wF = 0; //weight of foreground

float varMax = 0;
int threshold = 0;

//run an iteration to find the maximum value of the between class variance(as between class variance shld be maximise)
for (int t=0 ; t<256 ; t++)
{
wB += hist.at<float>(t); // Weight Background
if (wB == 0) continue;

wF = totalNumberOfPixels - wB; // Weight Foreground
if (wF == 0) break;

sumB += (float) (t * hist.at<float>(t));

float mB = sumB / wB; // Mean Background
float mF = (sum - sumB) / wF; // Mean Foreground

// Calculate Between Class Variance
float varBetween = (float)wB * (float)wF * (mB - mF) * (mB - mF);

// Check if new maximum found
if (varBetween > varMax) {
varMax = varBetween;
threshold = t;
}
}

cout<<"threshold value is: "<<threshold;

最佳答案

为了将 Otsu 的阈值化方法扩展到多级阈值化,类间方差方程变为:

multi between class variance

Please check out Deng-Yuan Huang, Ta-Wei Lin, Wu-Chih Hu, Automatic Multilevel Thresholding Based on Two-Stage Otsu's Method with Cluster Determination by Valley Estimation, Int. Journal of Innovative Computing, 2011, 7:5631-5644 for more information.

http://www.ijicic.org/ijicic-10-05033.pdf

这是我针对 2 个阈值的 Otsu Multi 的 C# 实现:

/* Otsu (1979) - multi */

Tuple < int, int > otsuMulti(object sender, EventArgs e) {
//image histogram
int[] histogram = new int[256];

//total number of pixels
int N = 0;

//accumulate image histogram and total number of pixels
foreach(int intensity in image.Data) {
if (intensity != 0) {
histogram[intensity] += 1;
N++;
}
}

double W0K, W1K, W2K, M0, M1, M2, currVarB, optimalThresh1, optimalThresh2, maxBetweenVar, M0K, M1K, M2K, MT;

optimalThresh1 = 0;
optimalThresh2 = 0;

W0K = 0;
W1K = 0;

M0K = 0;
M1K = 0;

MT = 0;
maxBetweenVar = 0;
for (int k = 0; k <= 255; k++) {
MT += k * (histogram[k] / (double) N);
}


for (int t1 = 0; t1 <= 255; t1++) {
W0K += histogram[t1] / (double) N; //Pi
M0K += t1 * (histogram[t1] / (double) N); //i * Pi
M0 = M0K / W0K; //(i * Pi)/Pi

W1K = 0;
M1K = 0;

for (int t2 = t1 + 1; t2 <= 255; t2++) {
W1K += histogram[t2] / (double) N; //Pi
M1K += t2 * (histogram[t2] / (double) N); //i * Pi
M1 = M1K / W1K; //(i * Pi)/Pi

W2K = 1 - (W0K + W1K);
M2K = MT - (M0K + M1K);

if (W2K <= 0) break;

M2 = M2K / W2K;

currVarB = W0K * (M0 - MT) * (M0 - MT) + W1K * (M1 - MT) * (M1 - MT) + W2K * (M2 - MT) * (M2 - MT);

if (maxBetweenVar < currVarB) {
maxBetweenVar = currVarB;
optimalThresh1 = t1;
optimalThresh2 = t2;
}
}
}

return new Tuple(optimalThresh1, optimalThresh2);
}

这是我用上面的代码对土壤图像扫描进行阈值化得到的结果:

(T1 = 110,T2 = 147)。

original scan

thresholded scan

image histogram

Otsu's original paper: "Nobuyuki Otsu, A Threshold Selection Method from Gray-Level Histogram, IEEE Transactions on Systems, Man, and Cybernetics, 1979, 9:62-66" also briefly mentions the extension to Multithresholding.

https://engineering.purdue.edu/kak/computervision/ECE661.08/OTSU_paper.pdf

希望这对您有所帮助。

关于opencv - 多 otsu(多阈值)与 openCV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22706742/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com