-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add conv command to apply arbitrary convolution kernel to image #479
Conversation
Hello, thanks for making a good start on what will be a useful feature. The instantiation of the Although the underlying operation is called I’d prefer the Please can you add tests to cover this work. I notice you added a couple of “make CI happy” commits. Were you able to run the tests locally as I’d expect these failures to show up there? |
I'll move the initialization of the kernel I'm happy to change the name to |
…hread safety change name from conv to convolve update docs
@@ -221,10 +221,8 @@ namespace sharp { | |||
|
|||
VipsImage *vips_matrix = kernel.get_image(); | |||
|
|||
int i = 0; | |||
for(int k : kernel_v) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C++11 range based loops are used elsewhere so this should work. What was the error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to fix the mysterious appveyor failure. I suppose this has nothing to do with it. I can go back on this commit.
@lovell thanks for all your feedback. Is there anything else left to do before you would be comfortable merging this? |
* Convolution with a kernel. | ||
*/ | ||
VImage Convolve(VImage image, int width, int height, double scale, double offset, std::vector<double> kernel_v) { | ||
VImage kernel = VImage::new_matrix(width, height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might it be possible to use new_from_memory instead here? NAN_METHOD(pipeline)
already contains a loop over the values of the kernel array - if it built a char*
instead of a std::vector
the loop and pointer logic would no longer be required here.
Thanks for all the updates - one comment inline. Are you able to use more extreme (or at least less tame) test cases, e.g. edge detection? The expected test cases are almost the same as the input so |
|
||
size_t kernelSize = baton->convKernelWidth * baton->convKernelHeight; | ||
|
||
baton->convKernel = std::unique_ptr<double[]>(new double[kernelSize]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be delete
d after use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, unique_ptr
will delete the pointer it's managing when it goes out of scope: http://en.cppreference.com/w/cpp/memory/unique_ptr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for confirming. I've not had the pleasure of using unique_ptr
until now and seeing a new
without a delete
gave me the usual twitch. It looks like a rather useful feature of C++11, so thanks for introducing it to sharp!
Thanks again Matt for all your work on this feature! |
It's always interesting to discover more about what people are using this module for in the survey at #35 should you be able to share details publicly. |
Thanks! |
This patch adds a
conv
operator to the sharp API so that an arbitrary convolution kernel can be applied to an image. Theconv
command has one argument that takes a structure containing all the ingredients for a vips convolution kernel, eg.:{ 'width': N , 'height': M , 'scale': Z , 'offset': Y , 'kernel': [[ 1, 2, 3], [ 4, 5, 6], [ 7, 8, 9]] }
One part of the patch that might need a little work: I couldn't find any documentation on testing whether a
VImage
object is empty, so I made abool
calledconvKernelValid
that keeps track of whether the user has issued aconv
command when building the pipeline. It would be cleaner to track this with theVImage
object itself.