Automatyczne obliczanie niskich i wysokich progów dla operacji Canny w opencv
W openCV progi niskie i wysokie dla operatora canny są obowiązkowe:
cvCanny(input,output,thresh1,thresh2)
W Matlab istnieje możliwość automatycznego obliczania tych wartości:
edge(input,'canny')
Przyjrzałem się kodowi Matlaba dla edge ' a i naprawdę nie jest to proste, aby obliczyć je automatycznie.
Czy wiesz o jakiejś implementacji operatora canny wraz z automatycznym obliczaniem progu dla opencv?
Dzięki
7 answers
Natknąłem się na tę odpowiedź, gdy szukałem sposobu, aby automatycznie obliczyć wartości progowe Canny ' ego.
Mam nadzieję, że pomoże to każdemu, kto szuka dobrej metody określania automatycznych wartości progowych dla algorytmu Canny ' ego...
Jeśli obraz składa się z oddzielnego pierwszego planu i tła, wtedy krawędź obiektu pierwszego planu może zostać wyodrębniona przez:
-
Oblicz próg Otsu używając:
double otsu_thresh_val = cv::threshold( orig_img, _img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU );
Nie potrzebujemy
_img
. Interesuje nas tylkootsu_thresh_val
, ale niestety obecnie w OpenCV nie istnieje metoda pozwalająca obliczyć tylko wartość progową. -
Użyj wartości progowej Otsu jako wyższego progu i połowy tego samego co próg dolny dla algorytmu Canny ' ego.
double high_thresh_val = otsu_thresh_val, lower_thresh_val = otsu_thresh_val * 0.5; cv::Canny( orig_img, cannyOP, lower_thresh_val, high_thresh_val );
Więcej informacji na ten temat można znaleźć w this paper: the Study on an Application of Otsu Method in Canny Operator . Wyjaśnienie Otsu implementację można znaleźć tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-21 02:48:34
Możesz użyć średniej wartości wejściowego obrazu w skali szarości i zdefiniować dolny i górny próg za pomocą odchylenia standardowego. Możesz mieć bardziej szczegółowe wyjaśnienie i Kod opencv tutaj: http://www.kerrywong.com/2009/05/07/canny-edge-detection-auto-thresholding/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-11 01:35:54
Dostępny jest również kod, który może to zrobić automatycznie, umieszczając to w kompilacji OpenCV. Znalazłem go na liście dyskusyjnej OpenCV-users, więc żadnych gwarancji. :)
Dyskusja: http://opencv-users.1802565.n2.nabble.com/Automatic-thresholding-in-cvCanny-td5871024.html GitHub (kod): https://gist.github.com/756833
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-13 13:24:23
Przejrzałem kod źródłowy programu Matlab Canny edge detection i udało mi się go napisać w Javie za pomocą OpenCV 3.
private static Mat getpartialedge(Mat image){
double nonEdgeRate = 0.6;
double thresholdRate = 0.6;
double w = image.cols();
double h = image.rows();
int bins = 256;
Mat sobel = new Mat();
Mat sobelx = new Mat();
Mat sobely = new Mat();
Mat sobelxabs = new Mat();
Mat sobelyabs = new Mat();
Size gsz = new Size(5, 5);
if(false) {
Imgproc.Canny(image, sobel, 41, 71);
}else {
//Imgproc.GaussianBlur(graycopy,graycopy, gsz, 2);
//Imgproc.dilate(image, image, kernel8);
Imgproc.GaussianBlur(image, image, gsz, 2);
int apertureSize = 3;
Imgproc.Sobel(image, sobelx, CvType.CV_16S, 1, 0, apertureSize, 1, 0);
Core.convertScaleAbs(sobelx, sobelxabs);
Imgproc.Sobel(image, sobely, CvType.CV_16S, 0, 1, apertureSize, 1, 0);
Core.convertScaleAbs(sobely, sobelyabs);
Core.addWeighted(sobelxabs, 1, sobelyabs, 1, 0, sobel);
sobel.convertTo(sobel, CvType.CV_8U);
Mat equalized = new Mat();
Imgproc.equalizeHist(sobel, equalized);
Imgcodecs.imwrite(filePath + "aftersobel(eq).png", equalized);
Imgcodecs.imwrite(filePath + "aftersobel.png", sobel);
Mat hist = new Mat();
List<Mat> matList = new ArrayList<Mat>();
matList.add(sobel);
Imgproc.calcHist(matList, new MatOfInt(0), new Mat(), hist, new MatOfInt(bins), new MatOfFloat(0f, 256f));
float accu = 0;
float t = (float) (nonEdgeRate * w * h);
float bon = 0;
float[] accutemp = new float[bins];
for (int i = 0; i < bins; i++) {
float tf[] = new float[1];
hist.get(i, 0, tf);
accu = accu + tf[0];
accutemp[i] = accu;
if (accu > t) {
bon = (float) i;
break;
}
}
Imgproc.threshold(sobel, sobel, bon, 255, Imgproc.THRESH_BINARY);
double ut = bon;
double lt = thresholdRate * bon;
Imgproc.Canny(image, sobel, lt, ut);
//Imgproc.dilate(sobel, sobel, kernel2);
}
return sobel;
}
Ścieżka pliku jest miejscem przechowywania obrazów wyjściowych. A obraz wejściowy powinien być obrazem w skali szarości z typem danych U8. Podstawową zasadą jest wykluczenie piksela bez krawędzi (60%) jako piksela bez krawędzi przez jasność. Histogram jest używany do sortowania jasności, a górny próg zostanie ustawiony tak, że poniżej niego znajduje się 60% pikseli. Dolny próg ustala się przez pomnożenie górnego progu przez próg (0,6).
Zauważ, że double nonEdgeRate = 0.6 i double thresholdRate = 0.6 jest dostrojony przeze mnie w moim konkretnym przypadku użycia. Oryginalne wartości to 0,7 i 0,4 oddzielnie w matlab.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-26 14:10:35
Zobacz ten link: http://www.pyimagesearch.com/2015/04/06/zero-parameter-automatic-canny-edge-detection-with-python-and-opencv/
Implementują podobne rozwiązanie za pomocą podstawowych statystyk w celu określenia niskiego i wysokiego progu wykrywalności krawędzi.
def auto_canny(image, sigma=0.33):
# compute the median of the single channel pixel intensities
v = np.median(image)
# apply automatic Canny edge detection using the computed median
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(image, lower, upper)
# return the edged image
return edged
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-19 16:34:52
Mam inne podejście do tego samego problemu. Rozwiązanie to obejmuje również dobór optymalnych progów wykrywania krawędzi.
- najpierw Oblicz medianę obrazu w skali szarości.
- Wybierz dwie wartości (dolny i górny próg) na podstawie mediany wartość obrazu w skali szarości.
Następujący pseudo-kod pokazuje, jak to zrobić:
v = np.median(gray_img)
sigma = 0.33
#---- apply optimal Canny edge detection using the computed median----
lower_thresh = int(max(0, (1.0 - sigma) * v))
upper_thresh = int(min(255, (1.0 + sigma) * v))
Napraw te progi jako parametry w wykrywaniu krawędzi canny funkcja.
Illustration: jeśli zaobserwujesz krzywą Gaussa w statystyce, wartości między 0,33 z obu stron krzywej są brane pod uwagę w rozkładzie. Każda wartość poza tymi punktami przyjmuje się za wartości odstające. Ponieważ obrazy są uważane za dane, koncepcja ta jest również przyjęta tutaj.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-20 12:00:41
Jak zasugerował Luca Del Tongo, można obliczyć progi z szarego obrazu, np. w Javie za pomocą OpenCV...
MatOfDouble mu = new MatOfDouble();
MatOfDouble stddev = new MatOfDouble();
Core.meanStdDev(greyMat, mu, stddev);
threshold1 = mu.get(0, 0)[0];
threshold2 = stddev.get(0, 0)[0];
Imgproc.Canny(greyMat, outputMat, threshold1, threshold2);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-22 17:36:17