L_Shape[] FindBestPair(List<L_Shape> targets)
        {
            L_Shape[] best_pair = new L_Shape[2];

            for (int i = 0; i < targets.Count; i++)
            {
                if (targets[i].isPaired)
                    continue;

                for (int j = i + 1; j < targets.Count; j++)
                {
                    if (targets[j].isPaired || targets[j].isRight == targets[i].isRight)
                        continue;

                    L_Shape right;
                    L_Shape left;

                    if (targets[j].isRight)
                    {
                        right = targets[j];
                        left = targets[i];
                    }
                    else
                    {
                        right = targets[i];
                        left = targets[j];
                    }
                    Rectangle leftBRect = left.shape.BoundingRectangle;
                    Rectangle rightBRect = right.shape.BoundingRectangle;
                    if (rightBRect.Left > leftBRect.Right)
                        if (Math.Abs(rightBRect.Y - leftBRect.Y) < rightBRect.Height / 2)
                        {
                            double ratio = (rightBRect.Left - leftBRect.Right) / (double)rightBRect.Width;
                            //ratio can't be greater than expected, but when viewing from an angle can be lesser.
                            if (ratio < expectedSpaceByEdgeRatio + (error * 4) && ratio > expectedSpaceByEdgeRatio - error)
                            {
                                right.isPaired = true;
                                left.isPaired = true;

                                //Got A Good Pair. Check If Best Pair.
                                if (best_pair[0] != null) //else it's the first pair, thus the best pair
                                {
                                    double yRatio = (double)(rightBRect.Y + leftBRect.Y) / (best_pair[0].shape.BoundingRectangle.Y + best_pair[1].shape.BoundingRectangle.Y);
                                    double areaRatio = (double)(right.shape.Area + left.shape.Area) / (best_pair[0].shape.Area + best_pair[1].shape.Area);

                                    if (0.3 * yRatio + 0.7 * areaRatio < 1)
                                        break;
                                }


                                best_pair[0] = left;
                                best_pair[1] = right;
                                break;
                            }
                        }
                }
            }
            return best_pair;
        }
        List<L_Shape> FindToteVisionTargets(ToteDetectionType tdt, Image<Gray, byte> thresh, float resolutionOffset, float imageWidth)
        {
            List<L_Shape> targets = new List<L_Shape>();
            Contour<Point> blob = thresh.FindContours();

            while (blob != null)
            {
                bool isL = false;

                if (blob.Area > 200 * resolutionOffset)
                    switch (tdt)
                    {
                        case ToteDetectionType.Math:
                            isL = IsL_ByMath(blob);
                            break;
                        case ToteDetectionType.Edges:
                            isL = IsL_ByEdges(blob);
                            break;
                        case ToteDetectionType.None:
                            isL = true;
                            break;
                    }

                if (isL)
                {
                    L_Shape s = new L_Shape(blob, IsRightL(blob));
                    targets.Add(s);
                }
                blob = blob.HNext;
            }
            return targets;
        }