Replies: 2 comments 3 replies
-
I didn't go too deep into your examples, but wouldn't loading the image into a floating point pixel type |
Beta Was this translation helpful? Give feedback.
-
In your ImageSharp example you are using You can verify this when you reload the image:
You can also achieve the same with:
Another way to achieve the same result is when you provide -1 to the Some more things I noticed:
Lastly I am not sure that |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Note, I am pretty new to image processing and my knowledge of the math and algorithms mentioned below is somewhat superficial, but I believe I have the concept right. Correct me if I'm wrong/misguided.
As I understand, calling
Mutate
on an image replaces the Image's pixel values with the result of the mutation.In the case of something like the Laplacian3x3 edge detection kernel, pixel values are very likely to undergo a multiplication operation whose product exceeds the MaxValue of the underlying datatype of most (all?) PixelFormats.
For example, if you have an L8 image and a pixel whose value is 50, the convolution kernel may multiply it by 8 (oversimplifying of course). The result is of course 400, but since it gets cast(?) back into a byte, it winds up being 144. Similarly, the edge detection kernels often use negative numbers, which leads to the same type of behavior.
By way of comparison, in OpenCV, when you run filters like Laplacian or Sobel, you can specify the depth of the resulting image in order to avoid this behavior and therefore retain the true results of the filter/mutation (see comment about the
ddepth
parameter on this page: https://docs.opencv.org/4.6.0/d5/db5/tutorial_laplace_operator.html).Interestingly, the resulting edge-detected image appears to be identical (or nearly so) in both approaches (ImageSharp allowing the overflow, and OpenCV allocating a larger datatype). I'm curious if somebody could explain why that is, but it's sort of beside the point of my main discussion/question.
The problem for me is I would like to retain the true results of the Laplacian filter. Is this possible?
A little more background...
I'm experimenting with using Laplacian edge detection to determine if an image is blurry (see: https://pyimagesearch.com/2015/09/07/blur-detection-with-opencv/).
The general idea is:
Since I'm basically trying to measure the differences between all of the pixel values, I think it's important that the actual numbers calculated by the kernel be retained, even though they are outside the bounds of the original PixelFormat.
Am I misunderstanding something, and/or is there a different API I should be using? I did look into Cloning the image to a larger PixelFormat like Short4, but that of course happens before any mutations and the pixel values appear to be scaled up, leading to the same behavior.
Here is some code and a test image:
Test image:

Code to load the bananas, convert to grayscale, apply Laplacian3x3, save image and output some stats based on the resulting pixels.
Resulting image and console output:

Here's the same operation in OpenCV.
Resulting image and output:

As mentioned, the resulting images are the same, but the results of any sort of analysis on the underlying data is very different.
Beta Was this translation helpful? Give feedback.
All reactions