이미지에서 그라디언트 및 가장자리를 감지하는 방법?


17

아래 왼쪽 그림과 같이 방사형 그래디언트의 중심 인 이미지에서 점을 찾을 수 있기를 원합니다. Hough 변환이나 다른 컴퓨터 비전 방법을 사용하는 방법에 대한 아이디어가 있습니까?

감사

여기에 이미지 설명을 입력하십시오

검색 이미지 예 :

여기에 이미지 설명을 입력하십시오


좋은 질문입니다!
Spacey

또한 그라디언트를 추정하는 방법의 예로 로버츠 크로스 ( en.wikipedia.org/wiki/Roberts_Cross )를 살펴보십시오 .
Spacey

더 작은 sobel 연산자처럼 보입니다. 나는 확실히 방사형 그라디언트하지만 찾아 그것을 사용하는 방법을 모르겠어요
waspinator을

@ waspinator : 이미지에서 sobel 연산자를 실행하고 출력을 보았습니까? 그것은 1D 함수의 미분을 취하는 것과 같은 2D와 같습니다. 따라서 로컬 최소 점 또는 최대 점에서 0을 교차해야합니까?
endolith

1
아마도 Hough와 유사한 간단한 접근법을 시도해 볼 수 있습니다. 이미지의 모든 픽셀에 대해 그라디언트 방향을 계산 하고이 픽셀에서 시작하는 그라디언트 방향으로 짧은 선 세그먼트를 누적기로 렌더링하십시오. 찾고있는 중심점은 누산기에서 가장 높은 피크 여야합니다 (큰 마진).
koletenbert

답변:


7

나는 opencv에서 일하고 있었고 거리 변환으로 생성 된 그라디언트의 피크를 찾으려고 노력했습니다. 이 경우 그레이 판매 이미지에서 형태 학적 작업 (침식 / 확장)을 사용하는 것이 매우 유용하다는 것을 깨달았습니다. 그레이 스케일 이미지를 침식하면 모든 픽셀이 가장 낮거나 높은 이웃 값을 갖습니다. 따라서 동일한 확장 / 침식 된 이미지에서 회색조 이미지를 빼서 그라디언트에서 최대 강도를 찾을 수 있습니다. 내 결과는 다음과 같습니다. 여기에 이미지 설명을 입력하십시오

OpenCV / Cpp에서이를 수행하는 방법 :

#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

여기까지 내가 가진 것입니다. 허프 공간을 채우는 방식은 최적이 아닙니다. 벡터화가 더 빨라질 수 있다고 확신합니다. Matlab R2011a를 사용하고 있습니다. 원본 이미지

제안에 감사드립니다.

여기에 이미지 설명을 입력하십시오

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 central에서 찾은 선 그리기 기능을 수정하여 픽셀 단위로 값을 증가시킵니다.

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

누구도 기여하기를 귀찮게하지 않았기 때문에 현상금이 귀하의 답변에 귀속된다고 생각합니다. 정확히 내가 원하는 것은 아니지만 3에 가장 가깝습니다.이 방법을 더 개선 했습니까?
케이프 코드

1

이미지 패치에 대해 방향 그라디언트 히스토그램을 실행합니다. 각 히스토그램의 피크는 패치의 주요 방향 (표시하는 화살표)을 제공합니다.

모든 화살표가 교차하는 곳을 찾으십시오. 해당 점이 객체 내부에 있으면 방사형 그래디언트의 중심이 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.