[TS().write()] fix many bugs in img writing
[class_parser_demo] update w/ new api
Merge branch 'oop' into traitcapture_v0

Pull in some bugfixes & update demo code
Initial commit of pipeline logic.

* timestream/manipulate/pipeline.py (ImagePipeline): New class holding
methods that initialize, run and print pipelines of computer vision
components.
(process): When run, this method goes through the totality of the pipeline.
(printCompList): Pretty prints the pipeline component information.

* timestream/manipulate/pipecomponents.py (PipeComponent): Parent class for
all pipeline components. Automatically inits the predefined variables
(__call__): Each pipeline component is a callable instance. When called, it
should execute the computer vision code.
(PCException, PCExBadRunExpects): Specific error classes for the pipeline
component exceptions.
(Tester): New pipeline component that can be used to test the ImagePipeline
class internals.
(ImageUndistorter): New pipeline component that should undistort image.
(ColorCardDetector): New pipeline components that should detect the position
of the color card.
(ImageColorCorrector): New pipeline component intended to correct the color
values in an image.
(TrayDetector): New pipeline component that detects the position of the tray
corners.
(PotDetector): New pipeline component that detects the position of the pot
corners.
(PlantExtractor): New pipeline component that should segment the plants.
Reduce footprint of the test images.

We reduced the test images to 5% of their original size. This moves from more
than 60Mb to just under 1Mb.
* tests/helpers.py (TS_MANIFOLD_JPG_SHAPE): To make the tests complete, we
changed the image size to (35, 52, 3)
initial working pipeline. Pot detection accuracy still needs improvement.
There is no need to hard code the settingPath

The setting path can be passed in the configuration (yaml) file. I remove
various lines that ended in spaces.
* timestream/manipulate/pipecomponents.py(ImageUndistorter, ColorCardDetector)
(ImageColorCorrector, TrayDetector, PotDetector, PlantExtractor): Remove
spaces ending lines.
* timestream/manipulate/pipeline.py(ImagePipeline): Removed settingPath from
the __init__ method. It should be in the configuration file.
(test): Removed test method. Was not needed and did not express the current
state of things.
the config file *.yml.
* util/pipeline_demo.py(settingFile, inputRootPath, outputRootPath): Changed
these variables to my local setup. These should not be set in code, but should
be gotten from a config file. Also removed settingPath from the ImagePipeline
instatiation line.
The initial datastructure should not be hardcoded.

* timestream/manipulate/pipeline.py(ImagePipeline): Removed the check for an
ndarray at class initialization.
Initialize the process with a TimeStreamImage

* timestream/manipulate/pipecomponents.py: Import TimeStreamImage
(ImageUndistorter): Expect a TimeStreamImage instead of an ndarray.
* timestream/manipulate/pipeline.py(ImagePipeline): Use the *args as initial
argument. Remember that ImagePipeline knows nothing about what its passing
along (It's not logical to call pixels on what it receives).
* util/pipeline_demo.py: Put the timestream instance in the context argument.
All components will have it available as context{"ts"}.
Raise an error if we don't find colorcardImage

* timestream/manipulate/pipecomponents.py(ColorCardDetector):Raise a
ValueException when we have problems setting the colorcardImage var.
Initial commit for the segmentation logic

* util/pipeline_demo.py: Put the image output writing logic into a pipeline
component of its own.
* timestream/manipulate/pipecomponents.py (PlantExtractor): We will expect the
segmentation method name (defaults to k-means-square) and User defined
arguments. Args are defined in the yaml file.
(PlantExtractor.runReturns): We are returning the image and the ImagePotMatrix
instance.
(PlantExtractor.__init__): Use ChamberHandler to call the segmentation method
on the different pot centers.
(ResultingImageWriter): New pipeline component that will write any image to an
output file defined by an output timeseries instance defined in the context.
* timestream/manipulate/pipeline.py (complist): Added
* ResultingImageWriter.actName to the list of possible pipecomponents.
(process): Visualize should default to False.
* timestream/manipulate/plantSegmenter.py: New file containing logic for plant
and pot segmentation.
(ImagePot): New class that will represent individual pot images.
(ImagePot.rect): All pots will be represented as rectangles in an image. This
was a bit tricky as matrices in cv2 are indexed (height, width, :).
(ImagePot.maskedImage): Will return the segmented part of the image on top of
a black ([:,:,:]=0) background.
(ImagePotMatrix): New class to represent the matrix of pots in an image. For
now we assume that pots are in trays and trays fit in pictures. We might want
to come up with something more general in the future.
(ImagePotMatrix.asTuple): Method that will convert the ImagePotMatrix into a
list of lists so it can be serialiazable by json.
(ImagePotMatrix.getPot): Will allow individual pots to be indexed.
(ImagePotMatrix.ImageTray): New inner class that represents the trays.
(PotSegmenter): New parent class that will hold logic for the rest of the pot
segmenter approaches.
(PotSegmenter_KmeansSquare): Simple pot segmenter. Will use k-means to try to
separate two colors in the ImagePot.
(ChamberHandler): New class that brings everything (ImagePots, ImagePotMatrix,
PotSegmenter...) together under one roof.
Fix rebase issues between all three branches
[logging] Refactor log setup func name

This changes the name of the function that can be used to setup the
module-wide logger, "timestreamlib". It was called
timestream.setup_debug_logging, it is not called
timestream.setup_module_logging.

Requisite changes to demo scripts and tests have also been made.
[setup_logging] Tiny whitespace only change

Forgot to fix indentation in last commit
[img.pixels] fix misc bugs in img.pixels loader

Following bugs are fixed:
 - Exceptions in scikit image reading the image are caught, and logged,
   and then opencv's imgread is used. This means we'll get broken JPEGs
   as a matrix. This may be a Bad Idea.
 - OpenCV's imread returns BGR, not RGB. The .pixels should always be
   RGB, so we invert this on the fly
[data/zeros] add zeros.jpg and truncated.jpg

Add files to test the reading of numpy arrays. Also add a truncated
jpeg to try crashing various readers.
[ts.util.imgmeta] Add get_exif_date function
[TSImage] get datetime from exif as fallback

If we add an image not from a timestream, the datetime parser failed. So
now we fall back to using get_exif_date to find the date from the exif
header.
[ts.util.imgmeta.get_exif_date] rewrite function

Now, we use get_exif_tag, and ensure we return None if we can't get the
date
[ts.util.imgmeta] Fix bug in get_exif_date

Typo from rewrite