Ejemplo n.º 1
0
        private void detectVerticalLines(int width, int height)
        {
            vertical_lines = new ArrayList();
            ArrayList[] horizontal_positions = new ArrayList[horizontal_magnitude.GetLength(0)];
            ArrayList[] horizontal_positions_used = new ArrayList[horizontal_magnitude.GetLength(0)];

            int max_y = height - (height / 4);
            if (ROI != null) max_y = ROI.by;
            int min_y = width / 4;
            if (ROI != null) min_y = ROI.ty;

            float bottom_spacing = 0;
            float top_spacing = 0;

            // detect the positions of horizontal disscontinuities
            for (int i = 0; i < horizontal_magnitude.GetLength(0); i++)
            {
                horizontal_positions[i] = new ArrayList();
                horizontal_positions_used[i] = new ArrayList();
                int n = 0;
                int prev_x = -1;
                for (int x = 0; x < width; x++)
                    if (horizontal_magnitude[i, x] > 0)
                    {
                        horizontal_positions[i].Add(x);
                        horizontal_positions_used[i].Add(false);

                        int y = (height - 1) * i / horizontal_magnitude.GetLength(0) + (height / (horizontal_magnitude.GetLength(0) * 2));
                        if (ROI != null)
                            y = ROI.ty + (i * (ROI.by - ROI.ty) / horizontal_magnitude.GetLength(0)) + ((ROI.by - ROI.ty) / (horizontal_magnitude.GetLength(0) * 2));

                        if (prev_x > -1)
                        {
                            if (i == 0) top_spacing += (x - prev_x);
                            if (i == horizontal_magnitude.GetLength(0)-1) bottom_spacing += (x - prev_x);
                            n++;
                        }
                        prev_x = x;
                    }
                if ((i == 0) && (n > 0)) top_spacing /= n;
                if ((i == horizontal_magnitude.GetLength(0) - 1) && (n > 0)) bottom_spacing /= n;
            }

            // calculate the vertical gradient using the top and bottom horizontal spacings
            if ((top_spacing > 0) && (bottom_spacing > 0))
            {
                if (bottom_spacing < top_spacing * 1.3f)
                    bottom_spacing = top_spacing * 1.3f;

                if (ROI != null)
                    vertical_gradient = (bottom_spacing - top_spacing) / (float)(ROI.by - ROI.ty);
                else
                    vertical_gradient = (bottom_spacing - top_spacing) / (float)(height*3/4);
            }

            float vertical_additive = 0.5f;

            int max_horizontal_difference = (int)(width * separation_factor * 1.9f);
            for (int j = 0; j < horizontal_positions[0].Count; j++)
            {
                int x = (int)horizontal_positions[0][j];
                int y = height / (horizontal_magnitude.GetLength(0) * 2);
                if (ROI != null) y = ROI.ty;

                bool drawn = false;
                calibration_line line = new calibration_line();

                for (int i = 1; i < horizontal_magnitude.GetLength(0); i++)
                {
                    int max_connectedness = min_connectedness;
                    int best_x = -1;
                    int best_y = -1;
                    int idx = -1;

                    for (int k = 0; k < horizontal_positions[i].Count; k++)
                    {
                        int x2 = (int)horizontal_positions[i][k];
                        int dx = x2 - x;
                        if (Math.Abs(dx) < max_horizontal_difference)
                        {
                            int y2 = (height - 1) * i / horizontal_magnitude.GetLength(0) + (height / (horizontal_magnitude.GetLength(0) * 2));
                            if (ROI != null) y2 = ROI.ty + (i * (ROI.by - ROI.ty) / horizontal_magnitude.GetLength(0)) + ((ROI.by - ROI.ty) / (horizontal_magnitude.GetLength(0) * 2));

                            // are these two connected?
                            if ((y < height) && (y2 < height))
                            {
                                int grid_width = (int)(top_spacing + (vertical_additive * (bottom_spacing - top_spacing) * y2 / height));
                                if (ROI != null)
                                    grid_width = (int)(top_spacing + (vertical_additive * (bottom_spacing - top_spacing) * (y2 - ROI.ty) / (ROI.by - ROI.ty)));

                                if (!(((x > width * 55 / 100) && (x>x2) && (x2 < x + grid_width)) ||
                                    ((x < width * 45 / 100) && (x < x2) && (x2 > x - grid_width))))
                                {
                                    int connectedness = pointsConnectedByIntensity(width, height, x, y, x2, y2);
                                    if (connectedness > max_connectedness)
                                    {
                                        best_x = x2;
                                        best_y = y2;
                                        max_connectedness = connectedness;
                                        idx = k;
                                    }
                                }
                            }
                        }
                        
                    }

                    if (best_x > -1)
                    {
                        horizontal_positions_used[i][idx] = true;
                        calibration_line temp_line = traceLine(width, height, x, y, best_x, best_y);
                        line.Add(temp_line);
                        x = best_x;
                        y = best_y;
                        drawn = true;
                    }
                }

                if (drawn)
                {
                    calibration_line temp_line = traceLine(width, height, x, y, x, max_y);
                    line.Add(temp_line);
                    if (line.points.Count > 0)
                        vertical_lines.Add(line);
                }
            }

            int index = horizontal_magnitude.GetLength(0) - 1;
            for (int j = 0; j < horizontal_positions[index].Count; j++)
            {
                if ((bool)horizontal_positions_used[index][j] == false)
                {
                    int x = (int)horizontal_positions[index][j];
                    int y = height - (height / (horizontal_magnitude.GetLength(0) * 2));
                    if (ROI != null) y = ROI.by - ((ROI.by - ROI.ty) / (horizontal_magnitude.GetLength(0) * 2));

                    bool drawn = false;
                    calibration_line line = new calibration_line();

                    for (int i = horizontal_magnitude.GetLength(0) - 2; i >= 0; i--)
                    {
                        int max_connectedness = min_connectedness;
                        int best_x = -1;
                        int best_y = -1;
                        int idx = -1;

                        for (int k = 0; k < horizontal_positions[i].Count; k++)
                        {
                            int x2 = (int)horizontal_positions[i][k];
                            int dx = x2 - x;
                            if (Math.Abs(dx) < max_horizontal_difference)
                            {
                                int y2 = height - ((height - 1) * i / horizontal_magnitude.GetLength(0) + (height / (horizontal_magnitude.GetLength(0) * 2)));
                                if (ROI != null) y2 = ROI.by - (i * (ROI.by - ROI.ty) / horizontal_magnitude.GetLength(0)) + ((ROI.by - ROI.ty) / (horizontal_magnitude.GetLength(0) * 2));

                                // are these two connected?
                                if ((y < height) && (y2 < height))
                                {
                                    int grid_width = (int)(top_spacing + (vertical_additive * (bottom_spacing - top_spacing) * y2 / height)); 
                                    if (ROI != null)
                                        grid_width = (int)(top_spacing + (vertical_additive * (bottom_spacing - top_spacing) * (y2 - ROI.ty) / (ROI.by - ROI.ty)));

                                    if (!(((x > width * 55 / 100) && (x > x2) && (x2 < x + grid_width)) ||
                                        ((x < width * 45 / 100) && (x < x2) && (x2 > x - grid_width))))
                                    {
                                        int connectedness = pointsConnectedByIntensity(width, height, x, y, x2, y2);
                                        if (connectedness > max_connectedness)
                                        {
                                            best_x = x2;
                                            best_y = y2;
                                            max_connectedness = connectedness;
                                            idx = k;
                                        }
                                    }
                                }
                            }
                        }

                        if (best_x > -1)
                        {
                            calibration_line temp_line = traceLine(width, height, best_x, best_y, x, y);
                            temp_line.Reverse();
                            line.Add(temp_line);
                            x = best_x;
                            y = best_y;
                            drawn = true;
                        }
                    }

                    if (drawn)
                    {
                        calibration_line temp_line = traceLine(width, height, x, min_y, x, y);
                        temp_line.Reverse();
                        line.Add(temp_line);
                        line.Reverse();
                        if (line.points.Count > 0)
                            vertical_lines.Add(line);
                    }
                }
            }

            // sort and prune
            detectLinesSort(width, height, false, vertical_lines);

            // remove first and last lines , because these are usually poorly detected                                  
            if (vertical_lines.Count > 2)
            {
                vertical_lines.RemoveAt(vertical_lines.Count - 1);
                vertical_lines.RemoveAt(0);
            }            

            updateAllLines(width, height, false, vertical_lines);

            // add index numbers to the lines
            indexLines(width, height, false, all_vertical_lines);

            // draw
            for (int i = 0; i < all_vertical_lines.Count; i++)
            {
                calibration_line line = (calibration_line)all_vertical_lines[i];
                line.Draw(lines_image, width, height, 255, 0, 0);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// trace along a line
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="tx"></param>
        /// <param name="ty"></param>
        /// <param name="bx"></param>
        /// <param name="by"></param>
        /// <returns></returns>
        private calibration_line traceLine(int width, int height,
                                           int tx, int ty, int bx, int by)
        {
            calibration_line line = new calibration_line();

            int step_size = 10;
            int radius_x = (int)(width * separation_factor / 4);
            int radius_x2 = (int)(width * separation_factor * 10 / 4);
            if (radius_x < 1) radius_x = 1;
            int radius_y = (int)(height * separation_factor / 4);
            int radius_y2 = (int)(height * separation_factor * 10 / 4);
            if (radius_y < 1) radius_y = 1;
            int dx = bx - tx;
            int dy = by - ty;

            if (ROI != null)
            {
                if (tx < ROI.tx) tx = ROI.tx;
                if (ty < ROI.ty) ty = ROI.ty;
                if (bx > ROI.bx) bx = ROI.bx;
                if (by > ROI.by) by = ROI.by;
            }

            if (dy > dx)
            {
                step_size = radius_y2 * 3 / 2; // *3 / 4;
                if (step_size < 1) step_size = 1;
                for (int y = ty; y < by; y += step_size * height / 240)
                {
                    int x = tx + (dx * (y - ty) / dy);

                    radius_x = (int)(width * separation_factor * 1.0f);
                    if (radius_x < 1) radius_x = 1;
                    radius_y = (int)(height * (separation_factor * 2.0f));
                    if (radius_y < 1) radius_y = 1;

                    int av_x = 0;
                    int av_y = 0;
                    int hits = 0;
                    for (int xx = x - radius_x; xx < x + radius_x; xx++)
                    {
                        if ((xx > 2) && (xx < width-2))
                        {
                            for (int yy = y - radius_y2; yy < y + radius_y2; yy++)
                            {
                                if ((yy > -1) && (yy < height))
                                {                                    
                                    if (edges_binary[xx, yy])
                                    {
                                        av_x += xx;
                                        av_y += yy;
                                        hits++;
                                    }                                    
                                }
                            }
                        }
                    }

                    if (hits > 0)
                    {
                        av_x /= hits;
                        av_y /= hits;

                        int n = (y * width) + av_x;
                        int intensity = calibration_image[n];
                        int min_x = av_x;
                        for (int xx = av_x - 3; xx <= av_x + 3; xx++)
                        {
                            if ((xx > -1) && (xx < width))
                            {
                                n = (y * width) + xx;
                                if (calibration_image[n] < intensity)
                                {
                                    intensity = calibration_image[n];
                                    min_x = xx;
                                }
                            }
                        }

                        line.Add(min_x, y);
                    }
                }
            }
            else
            {
                step_size = radius_x2 * 3 / 2; // *3 / 4;
                if (step_size < 1) step_size = 1;
                for (int x = tx; x < bx; x += step_size * width / 320)
                {
                    int y = ty + (dy * (x - tx) / dx);

                    radius_x = (int)(width * separation_factor * 0.5f);
                    if (radius_x < 1) radius_x = 1;
                    radius_y = (int)(height * separation_factor * 1.0f);
                    if (radius_y < 1) radius_y = 1;

                    int av_x = 0;
                    int av_y = 0;
                    int hits = 0;
                    //int max_diff = 0;

                    for (int xx = x - radius_x2; xx < x + radius_x2; xx++)
                    {
                        if ((xx > -1) && (xx < width))
                        {
                            for (int yy = y - radius_y; yy < y + radius_y; yy++)
                            {
                                if ((yy > 2) && (yy < height-2))
                                {                                    
                                    if (edges_binary[xx, yy])
                                    {
                                        av_x += xx;
                                        av_y += yy;
                                        hits++;
                                    }
                                    
                                }
                            }
                        }
                    }

                    if (hits > 0)
                    {
                        av_x /= hits;
                        av_y /= hits;

                        int n = (av_y * width) + x;
                        int intensity = calibration_image[n];
                        int min_y = av_y;
                        for (int yy = av_y - 2; yy <= av_y + 2; yy++)
                        {
                            if ((yy > -1) && (yy < height))
                            {
                                n = (yy * width) + x;
                                if (calibration_image[n] < intensity)
                                {
                                    intensity = calibration_image[n];
                                    min_y = yy;
                                }
                            }
                        }

                        line.Add(x, min_y);
                    }
                }
            }
            return (line);
        }
Ejemplo n.º 3
0
        private void detectHorizontalLines(int width, int height)
        {
            horizontal_lines = new ArrayList();
            ArrayList[] vertical_positions = new ArrayList[vertical_magnitude.GetLength(0)];
            ArrayList[] vertical_positions_used = new ArrayList[vertical_magnitude.GetLength(0)];

            int max_x = width - (width / 4);
            if (ROI != null) max_x = ROI.bx;
            int min_x = width / 4;
            if (ROI != null) min_x = ROI.tx;

            // detect the positions of horizontal disscontinuities
            for (int i = 0; i < vertical_magnitude.GetLength(0); i++)
            {
                vertical_positions[i] = new ArrayList();
                vertical_positions_used[i] = new ArrayList();
                for (int y = 0; y < height; y++)
                    if (vertical_magnitude[i, y] > 0)
                    {
                        vertical_positions[i].Add(y);
                        vertical_positions_used[i].Add(false);
                        
                        int x = (width - 1) * i / vertical_magnitude.GetLength(0) + (width / (vertical_magnitude.GetLength(0)*2));
                        if (ROI != null)
                            x = ROI.tx + (i * (ROI.bx - ROI.tx) / vertical_magnitude.GetLength(0)) + ((ROI.bx - ROI.tx) / (vertical_magnitude.GetLength(0)*2));                         
                    }
            }
            
            int max_vertical_difference = (int)((height * separation_factor) / 1.0f);
            for (int j = 0; j < vertical_positions[0].Count; j++)
            {
                int y = (int)vertical_positions[0][j];
                int x = width / (vertical_magnitude.GetLength(0) * 2);
                if (ROI != null) x = ROI.tx;

                bool drawn = false;
                calibration_line line = new calibration_line();

                for (int i = 1; i < vertical_magnitude.GetLength(0); i++)
                {
                    int max_connectedness = min_connectedness;
                    int best_x = -1;
                    int best_y = -1;
                    int idx = -1;

                    for (int k = 0; k < vertical_positions[i].Count; k++)
                    {
                        int y2 = (int)vertical_positions[i][k];
                        int dy = y2 - y;
                        if (Math.Abs(dy) < max_vertical_difference)
                        {
                            int x2 = (width - 1) * i / vertical_magnitude.GetLength(0) + (width / (vertical_magnitude.GetLength(0) * 2));
                            if (ROI != null) x2 = ROI.tx + (i * (ROI.bx - ROI.tx) / vertical_magnitude.GetLength(0)) + ((ROI.bx - ROI.tx) / (vertical_magnitude.GetLength(0) * 2));

                            // are these two connected?
                            int connectedness = pointsConnectedByIntensity(width, height, x, y, x2, y2);
                            if (connectedness > max_connectedness)
                            {
                                best_x = x2;
                                best_y = y2;
                                max_connectedness = connectedness;
                                idx = k;
                            }
                        }
                    }

                    if (best_x > -1)
                    {
                        vertical_positions_used[i][idx] = true;
                        calibration_line temp_line = traceLine(width, height, x, y, best_x, best_y);
                        line.Add(temp_line);
                        x = best_x;
                        y = best_y;
                        drawn = true;
                    }
                }

                if (drawn)
                {
                    calibration_line temp_line = traceLine(width, height, x, y, max_x, y);
                    line.Add(temp_line);
                    if (line.points.Count > 0)
                        horizontal_lines.Add(line);
                }
            }

            int index = vertical_magnitude.GetLength(0) - 1;
            for (int j = 0; j < vertical_positions[index].Count; j++)
            {
                if ((bool)vertical_positions_used[index][j] == false)
                {
                    int y = (int)vertical_positions[index][j];
                    int x = width - (width / (vertical_magnitude.GetLength(0) * 2));
                    if (ROI != null) x = ROI.bx - ((ROI.bx - ROI.tx) / (vertical_magnitude.GetLength(0) * 2));

                    bool drawn = false;
                    calibration_line line = new calibration_line();

                    for (int i = vertical_magnitude.GetLength(0) - 2; i >= 0; i--)
                    {
                        int max_connectedness = min_connectedness;
                        int best_x = -1;
                        int best_y = -1;
                        int idx = -1;

                        for (int k = 0; k < vertical_positions[i].Count; k++)
                        {
                            int y2 = (int)vertical_positions[i][k];
                            int dy = y2 - y;
                            if (Math.Abs(dy) < max_vertical_difference)
                            {
                                int x2 = width - ((width - 1) * i / vertical_magnitude.GetLength(0) + (width / (vertical_magnitude.GetLength(0) * 2)));
                                if (ROI != null) x2 = ROI.bx - (i * (ROI.bx - ROI.tx) / vertical_magnitude.GetLength(0)) + ((ROI.bx - ROI.tx) / (vertical_magnitude.GetLength(0) * 2));

                                // are these two connected?
                                int connectedness = pointsConnectedByIntensity(width, height, x, y, x2, y2);
                                if (connectedness > max_connectedness)
                                {
                                    best_x = x2;
                                    best_y = y2;
                                    max_connectedness = connectedness;
                                    idx = k;
                                }
                            }
                        }

                        if (best_x > -1)
                        {
                            calibration_line temp_line = traceLine(width, height, best_x, best_y, x, y);
                            temp_line.Reverse();
                            line.Add(temp_line);
                            x = best_x;
                            y = best_y;
                            drawn = true;
                        }
                    }

                    if (drawn)
                    {
                        calibration_line temp_line = traceLine(width, height, min_x, y, x, y);
                        temp_line.Reverse();
                        line.Add(temp_line);
                        line.Reverse();
                        if (line.points.Count > 0)
                            horizontal_lines.Add(line);                        
                    }
                }
            }

            // sort and prune
            detectLinesSort(width, height, true, horizontal_lines);

            // remove first and last lines, since they're often poorly detected
            if (horizontal_lines.Count > 2)
            {
                horizontal_lines.RemoveAt(horizontal_lines.Count - 1);
                horizontal_lines.RemoveAt(0);
            }

            updateAllLines(width, height, true, horizontal_lines);

            // add index numbers to the lines
            indexLines(width, height, true, all_horizontal_lines);

            // draw
            for (int i = 0; i < all_horizontal_lines.Count; i++)
            {
                calibration_line line = (calibration_line)all_horizontal_lines[i];
                line.Draw(lines_image, width, height, 255, 0, 0);
            }
        }
Ejemplo n.º 4
0
 /// <summary>
 /// adds a point to the line
 /// </summary>
 /// <param name="line"></param>
 public void Add(calibration_line line)
 {
     for (int i = 0; i < line.points.Count; i++)
         points.Add((calibration_point)line.points[i]);
 }