GithubHelp home page GithubHelp logo

rmislam / pythonsift Goto Github PK

View Code? Open in Web Editor NEW
894.0 9.0 253.0 373 KB

A clean and concise Python implementation of SIFT (Scale-Invariant Feature Transform)

License: MIT License

Python 100.00%
sift template-matching python computer-vision image-processing feature-matching opencv

pythonsift's People

Contributors

rmislam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pythonsift's Issues

question on smooth_histogram

I want to know what smooth method does the following code use?
Thanks!

smooth_histogram[n] =(6 * raw_histogram[n] + 4 * (raw_histogram[n - 1] + raw_histogram[(n + 1) % num_bins]) + raw_histogram[n - 2] + raw_histogram[(n + 2) % num_bins]) / 16.

Question on localizeExtremumViaQuadraticFit()

Hi!

I would like to ask for a comment on line 180 in pysift.py file. Here you are computing keypoint.octave field which is composed of three quantities. Can you please give some hint what does third value mean and maybe some small explanation why it should be like that. (to be more concrete the quantity is computed as 'int(round((extremum_update[2] + 0.5) * 255))')

Many thanks in advance!

Possible bug with pip instalation

Hi,

First of all, I love what you are doing. This is exactly what my class (and EVERY other source I've found) is missing; actual aplication of the theory.

That said, after installing via pip I tryed to run a test code:

import cv2
import pysift

image = cv2.imread('your_image.png', 0)
keypoints, descriptors = pysift.computeKeypointsAndDescriptors(image)

and got the following error: ModuleNotFoundError: No module named 'urlparse'

I suppose it's got to do with this thread In which it's explaind that urlparse implementation was changed between Python 2 and 3. I tryed to re install pysift directly from github but I'm not very experienced with that an simply running pip install git+https://github.com/mitsuhiko/flask-oauthhttps://github.com/rmislam/PythonSIFT didn't work.

I'm not sure if you are still checking these, but if you are I'd REALLY apreaciate any help.

I will anyway try to implement the method myself, but it'd be nice to have a bar to aim to.

Thank you!

EDIT: Wellp I just found the really dumb error in my comand line (apparently I copied your repositorie's link over something else), which is what I get for doing stuff tired. Still running pip install git+https://github.com/rmislam/PythonSIFT installs UNKNOWN, which I'd never seen before, so that's new and weird.

pysift uses urlparse

Hello,
Thanks for developing this library !

Trying to run it with Python 3, I faced :

File lib\site-packages\pysift\api.py:3
-> from urlparse import urljoin
ModuleNotFoundError: No module named 'urlparse'

Looking at this github answer, from urlparse import urljoin should be replaced by from urllib.parse import urljoin

No time to make a PR sorry, hope that helps still

question about generating img octave

Nice work! One question about line 78. Why do we use the image in the middle of gaussian_images_in_octave for downsampling instead of the last one? Is this for some special reason?
Screenshot 2020-06-18 at 21 31 27

Question generateBaseImage()

Hi!

What's the assumed_blur parameter for? what does it mean?
I hope someone is still reading theese...
EDIT: Also, what's the point of upsampling the image? isn't it the same as just bluring it but ending up with more pixels to go through?

Deprecated implementation

PythonSIFT/pysift.py:80: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
return array(gaussian_images)

Problem in 'localizeExtremumViaQuadraticFit'.

keypoint.octave = octave_index + image_index * (2 ** 8) + int(round((extremum_update[2] + 0.5) * 255)) * (2 ** 16)

when it comes to count keypoint.octave,why, image_index need to multiply by (2**8), and I'm confused about the int(round((extremum_update[2] + 0.5) * 255)) * (2 ** 16)

FindScaleSpaceExtrema error

Hi, I'm trying to compute the FindScaleSpaceExtrema function and it's taking a really long time with a Runtime warning below.
RuntimeWarning: overflow encountered in ubyte_scalars
dx = gaussian_image[region_y, region_x + 1] - gaussian_image[region_y, region_x - 1]
RuntimeWarning: overflow encountered in ubyte_scalars
gradient_magnitude = np.sqrt(dx * dx + dy * dy)
RuntimeWarning: overflow encountered in ubyte_scalars
dy = gaussian_image[region_y - 1, region_x] - gaussian_image[region_y + 1, region_x]

How can i resolve this issue? Thank you.

Calculation of number of Octaves

def computeNumberOfOctaves(image_shape):
    """Compute number of octaves in image pyramid as function of base image shape (OpenCV default)
    """
    return int(round(log(min(image_shape)) / log(2) - 1))

The function is called as such:

num_octaves = computeNumberOfOctaves(base_image.shape)

When I was executing these functions manually, I discovered that, taking min(image_shape) will lead to log(3)
(3 being the number of channels rather than smaller of the 2 dimensions).

My suggestion is that the return statement of the function should be:

return int(round(log(min(image_shape[:2])) / log(2) - 1))

Request you to verify if this logic is correct and make change if required.

Regards

Question about keypoint.octave

Thanks for providing such a handsome sift code. But I really could not figure out why you calculate keypoint.octave like this

keypoint.octave = octave_index + image_index * (2 ** 8) \
               + int(round((extremum_update[2] + 0.5) * 255)) * (2 ** 16)

Thanks.

computeNumberOfOctaves function always returns 1

Hi @rmislam , I found that when calculating the number of octaves in the function computeNumberOfOctaves, it always returned 1 because you applied a minimum function to the image shape (I guess you want to find the shorter side length of the image), but the image shape is consisted of three values: (hight, width, channel) so the minimum of those three values should always be 3 which is the number of channel of this image.

I am not sure if I missed something, but hope you could see this issue😃

How to implement dense sift?

Hello, I am trying to implement denseSIFT with your code. What would I change in order to generate the keypoints in a grid format as opposed to the local minima/extrema? Please let me know if you can help me with this!

About alberto98fx's "Error-input array"

I met the same kind of error when the queryImage(212x142) is larger than trainImag(215x133).

Traceback (most recent call last):
  File "D:/Download/PythonSIFT-master/template_matching_demo.py", line 55, in <module>
    newimg[hdif:hdif + h1, :w1, i] = img1
ValueError: could not broadcast input array from shape (142,212) into shape (0,212)

And I exchange the two Image, then it works smoothly. So it seems to be trainImage's size cannot be smaller than queryImage's(Logically, it really should be like this)

Thx for ur share, it helps me a lot!

Why using same gaussian_kernels to generate GaussianImages?

def generateGaussianImages(image, num_octaves, gaussian_kernels):
    """Generate scale-space pyramid of Gaussian images
    """
    logger.debug('Generating Gaussian images...')
    gaussian_images = []

    for octave_index in range(num_octaves):
        gaussian_images_in_octave = []
        gaussian_images_in_octave.append(image)  # first image in octave already has the correct blur
        for gaussian_kernel in gaussian_kernels[1:]:
            image = GaussianBlur(image, (0, 0), sigmaX=gaussian_kernel, sigmaY=gaussian_kernel)
            gaussian_images_in_octave.append(image)
        gaussian_images.append(gaussian_images_in_octave)
        octave_base = gaussian_images_in_octave[-3]
        image = resize(octave_base, (int(octave_base.shape[1] / 2), int(octave_base.shape[0] / 2)), interpolation=INTER_NEAREST)
    return array(gaussian_images, dtype=object)

gassian_kernel is:

print(gaussian_kernels)
array([1.6, 1.22627, 1.54501, 1.94659, 2.45255, 3.09002])

the first octave sigma is 1.6, we blur this image by 1.94659 to produce our last image, which has a blur of sqrt(1.6 ** 2 + 1.22627 **2 +1.54501 **2 +1.94659 ** 2) == 3.2. And 2 * 1.6 == 3.2, so we’ve moved up exactly one octave! Sounds good...
However, the next octave, which sigma is 3.2, still uses the same gaussian_kernels, and it will produce sqrt(3.2 ** 2 + 1.22627 **2 +1.54501 **2 +1.94659 ** 2) == 4.23, which is not equivalent to 3.2*2. I think it's wrong. Could you give me some advice?

Perspective transform raises error

I got the following error while matching two images.

OpenCV(4.1.2) /io/opencv/modules/core/src/matmul.dispatch.cpp:531: error: (-215:Assertion failed) scn + 1 == m.cols in function 'perspectiveTransform'

Error - input array

I'm getting this error with two pictures I used:

Traceback (most recent call last):
  File "template_matching_demo.py", line 55, in <module>
    newimg[hdif:hdif + h1, :w1, i] = img1
ValueError: could not broadcast input array from shape (1280,960) into shape (0,960)

It seems like it couldn't fit some points into the other picture, I suspect the issue is caused by different size:

img1 is 960 × 1280 while img2 is 1080 × 720.

Two questions about keypoint scale

HI, thank you for the great work, it helps me a lot when learning SIFT, I have to 2 questions about keypoint.size

  1. When computing keypoint.size in localizeExtremumViaQuadraticFit(), you used octave_index + 1 instead of octave_index, is this because the origin input image is doubled by linear interpolation?

  2. In computeKeypointsWithOrientations, the scale is muliplied by 0.5 and divided by 2 ** octave_index, it's a little different from the origin paper, am I missing something?

question about generateGaussianKernels function

generateGaussianKernels() function uses gaussian kernels generated from generateGaussianKernels(), however, (for example) the third image from the top of the 2nd octave don't have a blur factor=4*sigma

gaussian kernel generated by generateGaussianKernels() :[1.6, 1.2262735, 1.54500779, 1.94658784, 2.452547, 3.09001559]

1st octave:[1.6, sqrt(1.6 ** 2 + 1.22627 ** 2)=2.01587, sqrt(2.01587 ** 2 + 1.54501 ** 2) = 2.53984, sqrt(2.53984 ** 2 + 1.94659 ** 2) = 3.2, sqrt(3.2**2 + 2.452547**2)=4.03174, sqrt(4.03174**2 + 3.090015**2)=5.07967]

2nd octave: [3.2, sqrt(3.2 ** 2 + 1.22627 ** 2)=3.42691, sqrt(3.426913**2 + 1.54501 ** 2)=3.75909, sqrt(3.75909**2 + 1.94659 ** 2)=4.233198, sqrt(4.233198**2 + 2.452547**2)=4.892336, sqrt(4.892336**2 + 3.090015**2)=5.78646]

2nd_octave[-3] != 4*1.6

Strange results when using on non grayscale images

Your keypoint detection algorithm is very similar to OpenCV's SIFT. But descriptors extraction gives strange results when used on non grayscale images, for example Hue (from HSV), Saturation (from HSV), Cr (from YCrCb), Cb (from YCrCb). Have you tested descriptors after moving from Python 2 to Python 3?

Trouble getting installed and working

Hi. I am having trouble getting this working.

I have tried installing and removing and reinstalling various ways. I'm on Windows 10, using Visual Studio Code and Anaconda. I've installed: using Git Bash and the "git clone" command; downloading and unzipping; and with "pip install" from terminal. I've tried this in the folder I usually work from as well as "...\anaconda3\Lib\site-packages."

I have cycled multiple times now through the round of errors you see below.

[Running] python -u "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py"
Traceback (most recent call last):
  File "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py", line 7, in <module>
    import pysift
ModuleNotFoundError: No module named 'pysift'

[Done] exited with code=1 in 1.761 seconds

[Running] python -u "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py"
Traceback (most recent call last):
  File "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py", line 7, in <module>
    import pysift
  File "C:\Users\Scott\anaconda3\lib\site-packages\pysift\__init__.py", line 18, in <module>
    from pysift.core import from_key
  File "C:\Users\Scott\anaconda3\lib\site-packages\pysift\core.py", line 10, in <module>
    from pysift.api import SiftScience
  File "C:\Users\Scott\anaconda3\lib\site-packages\pysift\api.py", line 3, in <module>
    from urlparse import urljoin
ModuleNotFoundError: No module named 'urlparse'

[Done] exited with code=1 in 1.592 seconds

[Running] python -u "c:\Users\Scott\Desktop\Python2\tempCodeRunnerFile.py"
Traceback (most recent call last):
  File "c:\Users\Scott\Desktop\Python2\tempCodeRunnerFile.py", line 1, in <module>
    ur
NameError: name 'ur' is not defined

[Done] exited with code=1 in 0.283 seconds

[Running] python -u "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py"
Traceback (most recent call last):
  File "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py", line 18, in <module>
    kp1, des1 = pysift.computeKeypointsAndDescriptors(img1)
AttributeError: module 'pysift' has no attribute 'computeKeypointsAndDescriptors'

[Done] exited with code=1 in 1.983 seconds

[Running] python -u "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py"
Traceback (most recent call last):
  File "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py", line 18, in <module>
    kp1, des1 = pysift.computeKeypointsAndDescriptors(img1)
AttributeError: module 'pysift' has no attribute 'computeKeypointsAndDescriptors'

[Done] exited with code=1 in 1.579 seconds

[Running] python -u "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py"
Traceback (most recent call last):
  File "c:\Users\Scott\Desktop\Python2\TestTemplateMatchingW.py", line 18, in <module>
    kp1, des1 = pysift.computeKeypointsAndDescriptors(img1)
AttributeError: module 'pysift' has no attribute 'computeKeypointsAndDescriptors'

[Done] exited with code=1 in 1.581 seconds

(For ModuleNotFoundError: No module named 'urlparse', based on websearching and answers like this, I have gone into api.py and changed urlparse to urllib.parse. That leads me to the next error.)

Any help would be appreciated.

edgeThreshold

Hello, thank you for the share.
Is the edge threshold considered in the program? I did not find it, neither hessian matrix for edge effect elimination.

Mistake when calucalate the magnitude and orientation of keypoints' neighbourhoods.

Keypoints' neigbbourhoods need to be in the Gaussian scaled image but not the original image.

for example in your code:

for i in range(0, 3):  
    for j in range(1, doubled.shape[0] - 1):   
           for k in range(1, doubled.shape[1] - 1):   
                magpyrlvl1[j, k, i] = ( ((doubled[j+1, k] - doubled[j-1, k]) ** 2) + ((doubled[j, k+1] - doubled[j, k-1]) ** 2) ) ** 0.5 
                oripyrlvl1[j, k, i] = (36 / (2 * np.pi)) * (np.pi + np.arctan2((doubled[j, k+1] - doubled[j, k-1]), (doubled[j+1, k] - doubled[j-1, k]))) 

The doubled[j,k,i] maybe should be replaced by pyrlvl1[j,k,i+1].

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.