سؤال

أقوم بتنفيذ كاشف زاوية هاريس لأغراض تعليمية ، لكنني عالق في جزء استجابة هاريس. في الأساس ، ما أفعله ، هو:

  1. حساب تدرجات شدة الصورة في الاتجاه x و y
  2. إخراج طمس (1)
  3. حساب استجابة هاريس على إخراج (2)
  4. قم بقمع غير Maximas في إخراج (3) في إخراج 3 × 3 و 3 × 3

1 و 2 يبدو أنهما يعملان بشكل جيد ؛ ومع ذلك ، أحصل على قيم صغيرة جدًا مثل استجابة Harris ، ولا توجد جدوى تصل إلى العتبة. الإدخال هو التصوير الفوتوغرافي في الهواء الطلق القياسي.

[...]
[Ix, Iy] = intensityGradients(img);
g = fspecial('gaussian');
Ix = imfilter(Ix, g);
Iy = imfilter(Iy, g);
H = harrisResponse(Ix, Iy);
[...]

function K = harrisResponse(Ix, Iy)
    max = 0;
    [sy, sx] = size(Ix);
    K = zeros(sy, sx);
    for i = 1:sx,
        for j = 1:sy,
            H = [Ix(j,i) * Ix(j,i), Ix(j,i) * Iy(j,i)
                Ix(j,i) * Iy(j,i), Iy(j,i) * Iy(j,i)];
            K(j,i) = det(H) / trace(H);
            if K(j,i) > max,
                max = K(j,i);
            end
        end
    end
    max
end

بالنسبة لصورة العينة ، ينتهي Max إلى 6.4163e-018 والتي تبدو منخفضة للغاية.

هل كانت مفيدة؟

المحلول

يتم تعريف زاوية في اكتشاف زاوية هاريس على أنها "أعلى قيمة بكسل في المنطقة" (عادة ما تكون 3X3 أو 5x5) لذا فإن تعليقك حول عدم وجود جدوى من الوصول إلى "عتبة" يبدو غريباً بالنسبة لي. فقط جمع جميع وحدات البكسل التي لها قيمة أعلى من جميع وحدات البكسل الأخرى في 5x5 حي من حولهم.

بصرف النظر عن ذلك: لست متأكدًا بنسبة 100 ٪ ، لكنني أعتقد أنه يجب أن يكون لديك:

K(j,i) = det(H) - lambda*(trace(H)^2)عندما يكون Lambda ثابتًا إيجابيًا يعمل في قضيتك (والقيمة المقترحة Harris هي 0.04).

بشكل عام ، تكون اللحظة الوحيدة المعقولة لتصفية مدخلاتك قبل هذه النقطة:

[Ix, Iy] = intensityGradients(img);

الفلتره Ix2, Iy2 و Ixy لا معنى له بالنسبة لي.

علاوة على ذلك ، أعتقد أن رمز العينة الخاص بك خاطئ هنا (هل تعمل harrisResponse لديك اثنين أو ثلاثة متغيرات إدخال؟):

H = harrisResponse(Ix2, Ixy, Iy2);
[...]

function K = harrisResponse(Ix, Iy)

نصائح أخرى

الحل الذي قمت بتطبيقه مع Python ، إنه يعمل بالنسبة لي آمل أن تجد ما تبحث عنه

import numpy as np
import matplotlib.pyplot as plt
from PIL.Image import *
from scipy import ndimage

def imap1(im):
    print('testing the picture . . .')
    a = Image.getpixel(im, (0, 0))
    if type(a) == int:
        return im
    else:
        c, l = im.size
        imarr = np.asarray(im)
        neim = np.zeros((l, c))
        for i in range(l):
            for j in range(c):
                t = imarr[i, j]
                ts = sum(t)/len(t)
                neim[i, j] = ts
        return neim

def Harris(im):
    neim = imap1(im)
    imarr = np.asarray(neim, dtype=np.float64)
    ix = ndimage.sobel(imarr, 0)
    iy = ndimage.sobel(imarr, 1)
    ix2 = ix * ix
    iy2 = iy * iy
    ixy = ix * iy
    ix2 = ndimage.gaussian_filter(ix2, sigma=2)
    iy2 = ndimage.gaussian_filter(iy2, sigma=2)
    ixy = ndimage.gaussian_filter(ixy, sigma=2)
    c, l = imarr.shape
    result = np.zeros((c, l))
    r = np.zeros((c, l))
    rmax = 0
    for i in range(c):
        print('loking for corner . . .')
        for j in range(l):
            print('test ',j)
            m = np.array([[ix2[i, j], ixy[i, j]], [ixy[i, j], iy2[i, j]]], dtype=np.float64)
            r[i, j] = np.linalg.det(m) - 0.04 * (np.power(np.trace(m), 2))
            if r[i, j] > rmax:
                rmax = r[i, j]
    for i in range(c - 1):
        print(". .")
        for j in range(l - 1):
            print('loking')
            if r[i, j] > 0.01 * rmax and r[i, j] > r[i-1, j-1] and r[i, j] > r[i-1, j+1]\
                                     and r[i, j] > r[i+1, j-1] and r[i, j] > r[i+1, j+1]:
                result[i, j] = 1

    pc, pr = np.where(result == 1)
    plt.plot(pr, pc, 'r+')
    plt.savefig('harris_test.png')
    plt.imshow(im, 'gray')
    plt.show()
    # plt.imsave('harris_test.png', im, 'gray')

im = open('chess.png')
Harris(im)

التنفيذ المقترح غير فعال بشكل رهيب. لنبدأ بعد حساب التدرجات (والتي يمكن تحسينها أيضًا):

A = Ix.^2;
B = Iy.^2;
C = (Ix.*Iy).^4;
lambda = 0.04;

H = (A.*B - C) - lambda*(A+B).^2;

% if you really need max:
max(H(:))

لا حلقات مطلوبة ، لأن ماتلاب يكره الحلقات.

في الأساس ، سيكون للكشف عن ركن هاريس 5 خطوات:

  1. حساب التدرج
  2. تجانس غاوسي
  3. هاريس قياس الحساب
  4. قمع غير أقصى
  5. عتبة

إذا كنت تنفذ في MATLAB ، فسيكون من السهل فهم الخوارزمية والحصول على النتائج.

قد يساعدك الكود التالي لـ Matlab في حل شكوكك:

% Step 1: Compute derivatives of image
Ix = conv2(im, dx, 'same');
Iy = conv2(im, dy, 'same');

% Step 2: Smooth space image derivatives (gaussian filtering)
Ix2 = conv2(Ix .^ 2, g, 'same');
Iy2 = conv2(Iy .^ 2, g, 'same');
Ixy = conv2(Ix .* Iy, g, 'same');

% Step 3: Harris corner measure
harris = (Ix2 .* Iy2 - Ixy .^ 2) ./ (Ix2 + Iy2);

% Step 4: Find local maxima (non maximum suppression)
mx = ordfilt2(harris, size .^ 2, ones(size));

% Step 5: Thresholding
harris = (harris == mx) & (harris > threshold);

هناك وظيفة لذلك في صندوق أدوات نظام رؤية الكمبيوتر المسمى detectHarrisFeatures.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top