- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 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 的阈值化方法扩展到多级阈值化,类间方差方程变为:
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.
这是我针对 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)。
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/
我正在使用 Python 并尝试对图像进行 Otsu 阈值处理,但仅限于蒙版内部(是的,我有一个图像和一个蒙版图像)。这意味着图像上较少的像素将包含在用于计算 Otsu 阈值的直方图中。 我目前正在使
我想将 Otsu 阈值化应用于图像梯度(以去除噪声)。之后,我想计算梯度方向。不幸的是,当我这样做时,我只能得到 0 到 90 度之间的梯度方向。没有 Otsu 阈值,值介于 0 和 360 之间。
我正在使用 OpenCV 库中的 cvThresholding() 例程,使用 Otsu 的阈值方法执行二值化。有时这种方法会失败,这是可以理解的,因为 Otsu 为整个图像计算了一个阈值。为了改善结
我试图在使用 leptonica 处理后将图像保存为 jpeg。我将 python 与 ctypes 一起使用,我的代码是: import ctypes leptlib = "liblept.so"
我正在尝试实现多级 Otsu 阈值,更具体地说,我需要 3 个阈值/4 个类。 我知道关于 SO 的 2 个类似问题:#34856019 和 #22706742。问题是我没有得到好的结果:我已经阅读了
我正在尝试使用 OpenCV 分水岭算法 ( https://docs.opencv.org/3.1.0/d3/db4/tutorial_py_watershed.html ),但稍作改动。文档中有这
我正在使用图像比率和 Otsu 阈值在 2 个图像之间执行变化检测。代码的最后一行出错。 import cv2 import numpy as np image1 = cv2.imread( 'E:\
我正在 Android 平台上创建数独解决应用程序,但在处理图像时遇到了问题。我正在尝试使用 Sobel 过滤器使用 OpenCV 找到拼图的水平线,然后使用 Otsu 算法进行阈值处理: Mat k
我正在尝试对文档图像实现 Otsu 二值化技术,例如所示: 谁能告诉我如何在 MATLAB 中实现代码? 最佳答案 取自Otsu's method on Wikipedia I = imread('c
除了 OpenCV,我已经尝试环顾四周,但无法找到任何 Otsu 方法或中值滤波器在 Python 中的实现。这是我尝试过的仅有的两个 OpenCV 函数文档链接。 http://opencv.wil
这是我的例子。从左到右: 原始图片 灰度 + (3,3) 高斯模糊 Otsu 阈值化 + 反转像素 我想捕捉更多笔划的微弱部分。我知道 Otsu Thresholding 尝试在像素强度直方图的两个峰
我使用以下指令尝试了所有可能性: ret,thresh = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 但它总是给我同样的错误
我有图像,某些区域设置为 255 以不干扰感兴趣的区域。在做 Otsu 阈值时,这些区域会抵消阈值。 我找到了一个很好的answer如何做到这一点,但我的 python 实现很慢。考虑到我在 10,0
我将 Otsu 的二值化应用于一张图像并得到了这个结果 之后,我使用此代码在四个主要形状周围获取框: img = cv.imread('test_bin.jpg', 0) _, cnts, _ = c
我正在尝试使用 otsu 进行多阈值处理。我目前使用的方法实际上是通过最大化类间方差,我已经设法获得与 OpenCV 库给出的阈值相同的阈值。然而,这只是通过运行一次 otsu 方法。 关于如何进行多
我使用的是固定阈值,但事实证明它对我来说不太好。然后,有人告诉我大津阈值。我如何在我的代码中使用它?我读过它,但我不太了解。有人可以向我解释如何在 OpenCV 中使用 otsu 阈值吗? 现在这是我
为什么 Tesseract OCR 引擎使用全局阈值技术,例如 Otsu 二值化?局部阈值技术(例如 Sauvola、Niblack 等)在从图像中去除文本方面不是更有效吗? 最佳答案 Tessera
我尝试使用这两种方法,但自适应阈值似乎给出了更好的结果。我用过 cvSmooth( temp, dst,CV_GAUSSIAN,9,9, 0); 在原始图像上,只有我使用了阈值。 有什么我可以使用
我不需要阈值图像。我想要阈值。我在 OpenCV 中找到了这个。 cv::threshold( orig_img, thres_img, 0, 255, CV_THRESH_BINARY+CV_THR
如何像 Matlab 函数 graythresh 一样使用 OpenCV 仅获取 Otsu 阈值。 例如,如果我编写这段代码,我会像使用 Matlab 函数 im2bw 一样获得二进制图像: Mat
我是一名优秀的程序员,十分优秀!