Mean filter -> Fast and easy to use. This will likely be the only filter
that gets alot of action on the M4.
Median filter -> Works really well, but, slow. On grayscale at 160x120
you can get also 10 FPS with it for a 3x3 kernel. That said, it's still
slow. Also, the code only works for 3x3 and 5x5 kernels.
About the previous histogram filter... technically, that filter should be
better. However, it suffers from a startup cost. The operation of finding
the median point in the histogram costs too much to compute. This is
what causes it to be slow. On very large kernels it will be faster than
the sorting median alrogithm I put up... but, large kernels will be too
slow for anyone to use anyway. The paper Ibrahim linked to about it
showed it being used for like 7x7 kernels and up... so, I think the
researcher who thought of the idea was really thinking about the
algorithm for large kernels.
Mode filter -> Works great on grayscale. Not so much on color. I think it
needs to be run on the LAB color space instead of the RGB color space. I
say this because it causes pretty strong artifacts around edges. When we
get more flash we'll be able to have a reverse lookup table for LAB to
make the mode filter better. Until then...
Has a bias value that allows you to control if its really a midpoint,
min, max filter, or something inbetween. Run at 160x120 or lower. 320x240
is slow (seems to be the case for all convoltions at that res).
First, a few things:
The MLX 16x4 sensor has just too low of a resolution for mass appeal for
the price. The product is not going to sell very well. We need to look
into supporting sensors with a better res. Like the FLIR 1. The MLX
module was renamed to the "flir" module with this idea in mind.
The flir code now takes care of doing scaling and blending itself. I did
this to get rid of the user having to scale the image themselves and
blend themselves. Its too easy to run out of memory given our current
ultra small heap. In general, anything that requires multiple images in
RAM has got to go. When we do another OpenMV Cam with external RAM in
the MB range then maybe such functions will be safe. But, right now they
are definately not.
Anyway, moving on, I fixed a few bugs with the MLX math code. But, for
the most part was correct. I also added reconmended polling code for
brownouts as required by the datasheet.
Last, I designed this code like the LCD code to support a type value
when inited. This will allow the system to user a different sensor in the
future without any API changes to the user.
I will add test scripts for this next. Basic usage follows:
import flir
flir.init()
flir.display_ir(sensor.snapshot())
And that's it. Super easy. If the user wants the raw temp values they
can use flir.read_ir() to get the ta and to values. The display function
has a hidden alpha and scale argument for controling blending and the
min/max scaling.
The previous way we worked out scaling kinda sucked... it was a good
shot, but, controllable min and maxes that autoscale by default just
work better. If the user knows the temp range then they can just set the
min and max.'
Anyway, longest commit ever done.
The built-in mjpeg module allows you to record videos seamlessly. It
will automatically compress the frame buffer using the extra space in the
main ram. So... you don't have to pass it jpeg images. Gets 7 FPS at
320x240 while connected to the computer too (it has to compress the
frame twice in this situation).
Anyway, the module work like Gif.
You can now get the color stats for an area in the image. The stats
function returns the mean, median, mode, min, max, st_dev,
lower_quartile, and upper_quartile.
This function allows you to automate binary and threshold functions
based on what's in the iamge.
The morph function lets you convolve the image with a kernel. It's
decently fast right now. But, in the future we'll have to optimize it by
a lot (unrolling loops, using SIMD instructions, etc.).
Anyway, along with morph I added an edge detection test script showing
how you can use a high pass filter on an image to get all the edges in
it. This is not as good as canny edge dection... but, it's about the
same and fast enough.
We'll need a Hough Transform system in the future to make edge dection
useful. Not sure how that will be implemented... so, that's going to be
far away for now.
Added BMP file format reading and writing support code and modified the
ppm code to match. Upper level glue code has been left intact to be
altered in future commits.
Tested save() and ppm writing functionality still works. More
comprehensive tests coming soon.
... Kinda concerend that standard image file formats might not cut it for
the speed we'd like to have when using image files in function calls. I
think only grayscale is going to be fast. All other formats require a
lot of prep work.
I think I may modify some of this low level stuff in the future to
autodetect if an entire grayscale image can be read in or written out
in one go to speed that stuff up.
* Filter functions bypass the default line processing in sensor.c, and pre-process lines.
* Processing is done on the fly, i.e. filters are called from after each line is received.
* A new integral image implementation that uses a moving window.
* Integral image is computed in steps, each shift computes n new lines.
* This only requires (image_width * (feature_height+1) * 4) bytes.
* Allows Haar detector to run on QVGA, and allows a second squared
integral image for standard deviation calculations.
The alloc functions allow you to use the framebuffer as a storage space.
It's very simple but effective. You can alloc which puts some memory on a
stack... and then when you're done you can free which pops the stack.
Pops (frees) must be done in reverse order of pushes (allocs).
In general, functions should call the init code before using the stack.
It could be in a bad state.
Also, I added some wrappers for file system functions to make that stuff
easier. This will be used in the future.
And modified the rainbow table so that the RGB888 to RGB565 translation
is done using a rounding technique versus hard floor. This is also used
for the RGB565<->RGB888 LUTs.
Additionally, I added a bunch of stuff to the image library to make
working with images easier. I will using these helpers in the future.
Finally, I cleaned up trailing space in the font stuff (pet peeve).
* Add pre-compiled MicroPython library and headers.
* Change Makefile to link libmp.a remove libusbgeneric
* Change linker script to support MicroPython memory layout.
* Change OTG handle name in stm32f4xx_it.c
* Change main to init libmp and export Python functions.
* Add MicroPython bindings to src
Fixed issue with SCCB delay and optimization
Recompiled all libraries with optimization enabled (-O2)
Some more tweaks to the Sensor's registers
Added function to load CCM data into .ccm section in runtime