Comparing two images - Detect egg in a nest - vb.net

I have a webcam directly over a chicken nest. This camera takes images and uploads them to a folder on a server. I'd like to detect if an egg has been laid from this image.
I'm thinking the best method would be to compare the contrast as the egg will be much more reflective than the straw nest. (The camera has Infrared so the image is partly grey scale)
I'd like to do this in .NET if possible.

Try to resize your image to a smaller size, maybe 10 x 10 pixel. This averages out any small disturbing details.
Const N As Integer = 10
Dim newImage As New Bitmap(N, N)
Dim fromCamera As Image = Nothing ' Get image from camera here
Using gr As Graphics = Graphics.FromImage(newImage)
gr.SmoothingMode = SmoothingMode.HighSpeed
gr.InterpolationMode = InterpolationMode.Bilinear
gr.PixelOffsetMode = PixelOffsetMode.HighSpeed
gr.DrawImage(fromCamera, New Rectangle(0, 0, N, N))
End Using
Note: you do not need a high quality, but you need a good averaging. Maybe you will have to test different quality settings.
Since now, a pixel covers a large area of your original image, a bright pixel is very likely part of an egg. It might also be a good idea to compare the brightness of the brightest pixel to the average image brightness, since that would reduce problems due to global illumination changes.
EDIT (in response to comment):
Your code is well structured and makes sense. Here some thoughts:
Calculate the gray value from the color value with:
Dim grayValue = c.R * 0.3 + c.G * 0.59 + c.B * 0.11
... instead of comparing the three color components separately. The different weights are due to the fact, that we perceive green stronger than red and red stronger than blue. Again, we do not want a beautiful thumbnail we want a good contrast. Therefore, you might want to do some experiments here as well. May be it is sufficient to use only the red component. Dependent on lighting conditions one color component might yield a better contrast than others. I would recommend, to make the gray conversion part of the thumbnail creation and to write the thumbnails to a file or to the screen. This would allow you to play with the different settings (size of the thumbnail, resizing parameters, color to gray conversion, etc.) and to compare the (intermediate) results visually. Creating a bitmap (bmp) with the (end-)result is a very good idea.
The Using statement does the Dispose() for you. It does it even if an exception should occur before End Using (There is a hidden Try Finally involved).

Related

Difference between channel_shift_range and brightness_range in ImageDataGenerator (Keras)?

There are multiple pages (like this and this) that present examples about the effect of channel_shift_range in images. At first glance, it appears as if the images have only had a change in brightness applied.
This issue has multiple comments mentioning this observation. So, if channel_shift_range and brightness_range do the same, why do they both exist?
After long hours of reverse engineering, I found that:
channel_shift_range: applies the (R + i, G + i, B + i) operation to all pixels in an image, where i is an integer value within the range [0, 255].
brightness_range: applies the (R * f, G * f, B * f) operation to all pixels in an image, where f is a float value around 1.0.
Both parameters are related to brightness, however, I found a very interesting difference: the operation applied by channel_shift_range roughly preserves the contrast of an image, while the operation applied by brightness_range roughly multiply the contrast of an image by f and roughly preserves its saturation. It is important to note that these conclusions could not be fulfilled for large values of i and f, since the brightness of the image will be intense and it will have lost much of its information.
Channel shift and Brightness change are completely different.
Channel Shift: Channel shift changes the color saturation level(eg. light Red/dark red) of pixels by changing the [R,G,B] channels of the input image. Channel shift is used to introduce the color augmentation in the dataset so as to make the model learn color based features irrespective of its saturation value.
Below is the example of Channel shift from mentioned the article:
In the above image, if you observe carefully, objects(specially cloud region) are still clearly visible and distinguishable from their neighboring regions even after channel shift augmentation.
Brightness change: Brightness level of the image explains the light intensity throughout the image and used to add under exposure and over exposure augmentation in the dataset.
Below is the example of Brightness augmentation:
In the above image, at low brightness value objects(eg. clouds) have lost their visibility due to low light intensity level.

Shrinking a dirty rect

Trying to optimize a falling sand simulation and I'm implementing optimizations that the noita devs talked about in their GDC talk. At around 10:45 they talk about how they use dirty rects. I've started trying to implement a similar system.
Currently, I am able to create a dirty rect that covers the particles that need updating. I do this by every time a valid particle(particle is not air or solid like a wall) is set inside a chunk, I call a function to update the dirty rect giving the placed particles position as an argument. From there, I can easily calculate the new min/max of the rectangle from this position.
Here's a gif of that working.
and here's the code for updating the rect:
public void UpdateDirtyRect(int2 newPos)
{
minX = Math.Min(minX, newPos.x);
minY = Math.Min(minY, newPos.y);
maxX = Math.Max(maxX, newPos.x);
maxY = Math.Max(maxY, newPos.y);
dirtyrect = .(.(minX, minY), .(maxX, maxY));
//Inflate by two pixels. Not doing this will cause the rect to not change size as particles update
dirtyrect=dirtyrect.Inflate(2);
}
The problem, as can be seen in the gif, is that I currently have no way to shrink the dirty rect. I can do a few things, such as detecting when a particle is erased/replaced with air/solid particle on the boundary edge of the dirty rect, but I'm unsure on what to do from there.
Here’s one approach that might work for you.
Keep the dirty rectangle updated by the previous frame.
Compute the dirty rectangle updated by one frame only.
Combine these two rectangles into a single one that contains both of them.
Use the rectangle from step 3 to update the screen.
Replace the previous frame rectangle with the one you have computed on step 2. Not the combined one you computed on step 3, doing so would cause the same problem you’re describing.

Simulate Camera in Numpy

I have the task to simulate a camera with a full well capacity of 10.000 Photons per sensor element
in numpy. My first Idea was to do it like that:
camera = np.random.normal(0.0,1/10000,np.shape(img))
Imgwithnoise= img+camera
but it hardly shows an effect.
Has someone an idea how to do it?
From what I interpret from your question, if each physical pixel of the sensor has a 10,000 photon limit, this points to the brightest a digital pixel can be on your image. Similarly, 0 incident photons make the darkest pixels of the image.
You have to create a map from the physical sensor to the digital image. For the sake of simplicity, let's say we work with a grayscale image.
Your first task is to fix the colour bit-depth of the image. That is to say, is your image an 8-bit colour image? (Which usually is the case) If so, the brightest pixel has a brightness value = 255 (= 28 - 1, for 8 bits.) The darkest pixel is always chosen to have a value 0.
So you'd have to map from the range 0 --> 10,000 (sensor) to 0 --> 255 (image). The most natural idea would be to do a linear map (i.e. every pixel of the image is obtained by the same multiplicative factor from every pixel of the sensor), but to correctly interpret (according to the human eye) the brightness produced by n incident photons, often different transfer functions are used.
A transfer function in a simplified version is just a mathematical function doing this map - logarithmic TFs are quite common.
Also, since it seems like you're generating noise, it is unwise and conceptually wrong to add camera itself to the image img. What you should do, is fix a noise threshold first - this can correspond to the maximum number of photons that can affect a pixel reading as the maximum noise value. Then you generate random numbers (according to some distribution, if so required) in the range 0 --> noise_threshold. Finally, you use the map created earlier to add this noise to the image array.
Hope this helps and is in tune with what you wish to do. Cheers!

Detect if a quad is actually visible 2D in OpenGL

I currently have 16 tiles, with individual images that make up 1 big map. I pan by transforming right at the beginning before any actual drawing with this:
GL.Translate(G_.Pan(0), G_.Pan(1), 0)
Then I zoom by doing this:
GL.Ortho(-G_.Size * 1.5 ^ G_.ZoomFactor, G_.Size * 1.5 ^ G_.ZoomFactor, G_.Size * 1.5 ^ G_.ZoomFactor, -G_.Size * 1.5 ^ G_.ZoomFactor, -1, 1)
G_.Size is a constant that only varies on startup depending on parameters, zoom factor ranges from -1 to -13
What I want to be able to do is check if 1 of the 16 tiles is within the visible area, so then I stop them drawing when they are not on screen. I had found some quite complex methods for doing it, but it was 3D and seemed like a lot of work for something that should be simple. I would of thought it would of been something like just checking if a point is within the bounds of visible area, but I have no idea on how to get the visible area.
Andon M Coleman already suggested you to implement projection volume culling (a generalized form of frustum culling). This is however outside the scope of OpenGL. You must understand that OpenGL is not a "magical" scene graph that does scene management and the likes. It's mere drawing API; what it does is putting shaded, textured points, lines or triangles on the screen and that's it. The rest is up to you, or the libraries you choose to implement it.
In the case of projection volume culling you're testing if a given piece of geometry intersects with the volume defined by the planes that form the borders of the volume. Your projection matrix defines such planes, specifically it transform the view space vertex position volume into the range [-1;1]×[-1;1]×[0;1] of perspective divided clip space. So by inverting the projection matrix and unprojection the corners of the [-1;1]×[-1;1]×[0;1] cube through that you determine the limiting planes of the projection volume in view space.
You then use that information to intersect your quads with the volume to see if they cross it, i.e. are in any way visible.

Low quality image into a label

I'm trying to pass an image showing to the user a countdown. For this, I'm using a separate thread where I'm checking when the countdown timer should be started, and when so, I draw an image for every 6 seconds passed.
What's annoying is when I pass the drawn image to the UI, the quality of the image is changed and it looks bad to the user.
This is my little script that handles the drawings:
Try
remainingTime = (#12:04:00 AM# - (DateTime.Now - local_DateTimeclick)).ToString("HH:mm:ss")
remainingTimeInSeconds = Convert.ToDateTime(remainingTime).Minute * 60 + Convert.ToDateTime(remainingTime).Second
If remainingTimeInSeconds Mod 6 = 0 Then
g.ResetTransform()
g.TranslateTransform(52, 52)
g.RotateTransform(230 - remainingTimeInSeconds / 6 * 9)
'g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
'g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
'g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
'g.CompositingMode = Drawing2D.CompositingMode.SourceCopy
'g.PixelOffsetMode = Drawing2D.PixelOffsetMode.
g.DrawImage(Tick, 10, 10)
End If
Catch
remainingTime = "Times Up"
End Try
In the above section,
- *local_DateTimeClick* is the variable that is set when the countdown should start
- Tick is a Bitmap that represents the image i have to draw for every 6 elipsed seconds
- g is a Graphics object from image that i return into the main window.
Also tried with changing the properties of g, but there was no positive effect.
Anyone have any idea what can i do to make this properly work without changing the quality of the returned image? Any tip/advice is welcomed.
Because Drawing2D.SmoothingMode only applies for 2D vector drawing methods such as Graphics.DrawEllipse and Graphics.DrawLine.
It doesn't affect drawing bitmaps with Graphics.DrawImage.
From the .NET documentation:
The smoothing mode specifies whether lines, curves, and the edges of filled areas use smoothing (also called antialiasing).
You have two options at this point:
Pre-render every possible orientation of the image, and then just display different Image objects at each tick
use the .NET vector drawing methods to render your image instead of using a pre-rendered bitmap.
Without knowing the actual image you're transforming, I can't say which would be more appropriate.
from a graphic designer perspective followed at my company, i think your should crop your images to fit in the label:
1. it enhance performance by saving processing power.
2. it look better ?!.
regards