छवियों में स्नातक और किनारों का पता लगाने के लिए कैसे?


17

मैं उन छवियों में बिंदुओं को खोजने में सक्षम होना चाहता हूं जो नीचे दी गई तस्वीर में दिखाए गए एक रेडियल ग्रेडिएंट का केंद्र हैं। किसी भी विचार पर कि मैं किसी परिवर्तन या किसी अन्य कंप्यूटर दृष्टि विधि का उपयोग कैसे कर सकता हूं?

धन्यवाद

यहां छवि विवरण दर्ज करें

उदाहरण खोज छवि:

यहां छवि विवरण दर्ज करें


बड़ा अच्छा सवाल!
स्पेसी

इसके अलावा, राबर्ट्स क्रॉस पर एक नज़र डालें: ( en.wikipedia.org/wiki/Roberts_Cross ) ग्रेडिएंट का अनुमान लगाने के तरीके के एक उदाहरण के रूप में।
स्पेसी

एक छोटे sobel ऑपरेटर की तरह दिखता है। मुझे यकीन नहीं है कि कैसे उपयोग करने के लिए कि एक रेडियल ढाल खोजने के लिए हालांकि
waspinator

@waspinator: अच्छी तरह से आप अपनी छवि पर एक sobel ऑपरेटर चला रहे हैं और उत्पादन में देखा है? यह 1 डी फ़ंक्शन के व्युत्पन्न लेने के 2 डी के बराबर है, इसलिए इसे स्थानीय मिनीमा या मैक्सिमा पर 0 पार करना चाहिए?
एंडोलिथ

1
एक सरल हाफ़-जैसे दृष्टिकोण के लिए, जो शायद आप यह काम कर सकते हैं: छवि के प्रत्येक पिक्सेल के लिए, ढाल दिशा की गणना करें और इस पिक्सेल में एक संचयकर्ता में शुरू होने वाले ढाल की दिशा में एक छोटी रेखा खंड को प्रस्तुत करें। आप जिस केंद्र बिंदु की तलाश कर रहे हैं, वह संचायक (बड़े अंतर से) में सबसे ऊंची चोटियां होनी चाहिए।
कोलेटेनबर्ट

जवाबों:


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)

मैंने एक ड्रॉ लाइन फ़ंक्शन को संशोधित किया जो मुझे एक पिक्सेल द्वारा एक मान द्वारा पिक्सेल सेट करने के बजाय एक पिक्सेल द्वारा वेतन वृद्धि के लिए मिला।

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

छवि के पैच पर ओरिएंटेड ग्रैडिएंट्स का हिस्टोग्राम चलाएं - उन हिस्टोग्राम्स में से प्रत्येक आपको उस पैच की प्रमुख दिशा देगा (जैसे आपके द्वारा दिखाए गए तीर)।

खोजें कि वे सभी तीर कहाँ से काटते हैं - यदि वह बिंदु वस्तु के अंदर है तो यह एक रेडियल ढाल का केंद्र हो सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.