Görüntülerdeki Degradeleri ve Kenarları Algılama


17

Aşağıdaki sol resimde gösterildiği gibi bir radyal degradenin merkezi olan görüntülerdeki noktaları bulmak istiyorum. Bir Hough dönüşümü veya başka bir bilgisayar görme yöntemini nasıl kullanabileceğim hakkında bir fikrin var mı?

Teşekkürler

resim açıklamasını buraya girin

örnek arama resmi:

resim açıklamasını buraya girin


Harika bir soru!
Spacey

Ayrıca, degradeleri tahmin etmenin bir örneği olarak Roberts 'Cross'a ( en.wikipedia.org/wiki/Roberts_Cross ) bir göz atın .
Spacey

daha küçük bir sobel operatörü gibi görünüyor. Yine de radyal bir gradyan bulmak için nasıl kullanılacağından emin değilim
waspinator

@ waspinator: resminizde bir sobel operatörü çalıştırdınız ve çıktıya baktınız mı? Bir 1D fonksiyonunun türevini almanın 2D eşdeğeri gibi, bu yüzden yerel minima veya maxima'da 0'ı geçmelidir?
endolith

1
Muhtemelen işe yarayacak basit bir Hough benzeri yaklaşım için bunu deneyebilirsiniz: görüntünün her pikseli için degrade yönünü hesaplayın ve bu pikselden başlayarak degrade yönünde kısa bir çizgi segmentini bir akümülatöre dönüştürün. Aradığınız merkez noktalar akümülatördeki en yüksek zirveler olmalıdır (büyük bir farkla).
koletenbert

Yanıtlar:


7

Opencv'de çalışıyordum ve mesafe dönüşümü tarafından üretilen bir degradenin zirvesini bulmaya çalışıyordum. Gri-skaler görüntülerde morfolojik operasyonların (erozyon / dilatasyon) kullanılmasının bu durumda çok yararlı olduğunu fark ettim. Gri tonlamalı bir görüntüyü dilate ederseniz, herhangi bir piksel alt / en yüksek komşunun değerini alacaktır. Bu nedenle, aynı dilate / aşınmış görüntüden gri tonlamalı görüntü çıkararak degradelerde yoğunluk zirveleri bulabilirsiniz. İşte benim sonuç: resim açıklamasını buraya girin

Ve bunu OpenCV / Cpp'de yapmanın bir yolu:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

int main( int argc, char** argv ){

    cv::Mat objects, img ,peaks,BGR;
    std::vector<std::vector<cv::Point> > contours;
    /* Reads the image*/
    BGR=cv::imread(argv[1]);
    /* Converts it to Grayscale*/
    cv::cvtColor(BGR,img,CV_BGR2GRAY);
    /* Devine where are the objects*/
    cv::threshold(img,objects,0,255,cv::THRESH_BINARY);
    /* In order to find the local maxima, "distance"
     * is subtracted from the result of the dilatation of
     * "distance". All the peaks keep the save value */
    cv::dilate(img,peaks,cv::Mat(),cv::Point(-1,-1),3);
    cv::dilate(objects,objects,cv::Mat(),cv::Point(-1,-1),3);

    /* Now all the peaks should be exactely 0*/
    peaks=peaks-img;

    /* And the non-peaks 255*/
    cv::threshold(peaks,peaks,0,255,cv::THRESH_BINARY);
    peaks.convertTo(peaks,CV_8U);

    /* Only the zero values of "peaks" that are non-zero
     * in "objects" are the real peaks*/
    cv::bitwise_xor(peaks,objects,peaks);

    /* The peaks that are distant from less than
     * 2 pixels are merged by dilatation */
    cv::dilate(peaks,peaks,cv::Mat(),cv::Point(-1,-1),1);

    /* In order to map the peaks, findContours() is used.
     * The results are stored in "contours" */
    cv::findContours(peaks, contours, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
    /* just draw them and save the image */
    cv::drawContours(BGR,contours,-1,cv::Scalar(255,0,0),-1);
    cv::imwrite("result.png",BGR);

    return 1;
}

5

İşte şimdiye kadar sahip olduğum şey. Hough alanımı doldurma şeklim optimal olmaktan çok uzak. Daha hızlı hale getirmek için yapabileceğim bir vektörizasyon olduğundan eminim. Matlab R2011a kullanıyorum. Gerçek görüntü

Öneriler takdir, teşekkür ederim.

resim açıklamasını buraya girin

clear all; clc; close all;

%% read in image and find gradient information
img = rgb2gray(imread('123.png'));
[rows, columns] = size(img);
[dx, dy] = gradient(double(img));
[x y] = meshgrid(1:columns, 1:rows);
u = dx;
v = dy;
imshow(img);
hold on
quiver(x, y, u, v)


%% create Hough space and populate
hough_space = zeros(size(img));

for i = 1:columns
  for j = 1:rows

    X1 = i;
    Y1 = j;
    X2 = round(i + dx(j,i));
    Y2 = round(j + dy(j,i));
    increment = 1;

    slope = (Y2 - Y1) / (X2 - X1);
    y_intercept = Y1 - slope * X1;

    X3 = X1 + 5;

    if X3 < columns && X3 > 1
      Y3 = slope * X3 + y_intercept;
      if Y3 < rows && Y3 > 1
        hough_space = func_Drawline(hough_space, Y1, X1, floor(Y3), floor(X3), increment);
      end
    end
  end
end

imtool(hough_space)

Matlab'ın merkezinde bulduğum bir çizgi çizme işlevini, bir pikseli bir değere ayarlamak yerine bir piksel değerinde artırmak için değiştirdim

function Img = func_DrawLine(Img, X0, Y0, X1, Y1, nG)
% Connect two pixels in an image with the desired graylevel
%
% Command line
% ------------
% result = func_DrawLine(Img, X1, Y1, X2, Y2)
% input:    Img : the original image.
%           (X1, Y1), (X2, Y2) : points to connect.
%           nG : the gray level of the line.
% output:   result
%
% Note
% ----
%   Img can be anything
%   (X1, Y1), (X2, Y2) should be NOT be OUT of the Img
%
%   The computation cost of this program is around half as Cubas's [1]
%   [1] As for Cubas's code, please refer  
%   http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=4177  
%
% Example
% -------
% result = func_DrawLine(zeros(5, 10), 2, 1, 5, 10, 1)
% result =
%      0     0     0     0     0     0     0     0     0     0
%      1     1     1     0     0     0     0     0     0     0
%      0     0     0     1     1     1     0     0     0     0
%      0     0     0     0     0     0     1     1     1     0
%      0     0     0     0     0     0     0     0     0     1
%
%
% Jing Tian Oct. 31 2000
% scuteejtian@hotmail.com
% This program is written in Oct.2000 during my postgraduate in 
% GuangZhou, P. R. China.
% Version 1.0

Img(X0, Y0) = Img(X0, Y0) + nG;
Img(X1, Y1) = Img(X1, Y1) + nG;
if abs(X1 - X0) <= abs(Y1 - Y0)
   if Y1 < Y0
      k = X1; X1 = X0; X0 = k;
      k = Y1; Y1 = Y0; Y0 = k;
   end
   if (X1 >= X0) & (Y1 >= Y0)
      dy = Y1-Y0; dx = X1-X0;
      p = 2*dx; n = 2*dy - 2*dx; tn = dy;
      while (Y0 < Y1)
         if tn >= 0
            tn = tn - p;
         else
            tn = tn + n; X0 = X0 + 1;
         end
         Y0 = Y0 + 1; Img(X0, Y0) = Img(X0, Y0) + nG;
      end
   else
      dy = Y1 - Y0; dx = X1 - X0;
      p = -2*dx; n = 2*dy + 2*dx; tn = dy;
      while (Y0 <= Y1)
         if tn >= 0
            tn = tn - p;
         else
            tn = tn + n; X0 = X0 - 1;
         end
         Y0 = Y0 + 1; Img(X0, Y0) = Img(X0, Y0) + nG;
      end
   end
else if X1 < X0
      k = X1; X1 = X0; X0 = k;
      k = Y1; Y1 = Y0; Y0 = k;
   end
   if (X1 >= X0) & (Y1 >= Y0)
      dy = Y1 - Y0; dx = X1 - X0;
      p = 2*dy; n = 2*dx-2*dy; tn = dx;
      while (X0 < X1)
         if tn >= 0
            tn = tn - p;
         else
            tn = tn + n; Y0 = Y0 + 1;
         end
         X0 = X0 + 1; Img(X0, Y0) = Img(X0, Y0) + nG;
      end
   else
      dy = Y1 - Y0; dx = X1 - X0;
      p = -2*dy; n = 2*dy + 2*dx; tn = dx;
      while (X0 < X1)
         if tn >= 0
            tn = tn - p;
         else
            tn = tn + n; Y0 = Y0 - 1;
         end
         X0 = X0 + 1; Img(X0, Y0) = Img(X0, Y0) + nG;
      end
   end
end

Sanırım başka kimse katkıda bulunmaya zahmet etmediği için ödülün cevabını sana vereceğim. Tam olarak istediğim şey değil ama 3'ün en yakını. Bu yöntemi daha da geliştirdiniz mi?
Cape Code

1

Görüntünün yamaları üzerine Yönlü Degradelerin Histogramını çalıştırın - bu histogramların her birindeki tepe noktası size bu yamanın baskın yönünü verecektir (gösterdiğiniz oklar gibi).

Tüm bu okların kesiştiği yeri bulun - bu nokta nesnenin içindeyse, radyal bir gradyanın merkezi olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.