Java image analysis - counting vertical lines

前端 未结 4 1896
星月不相逢
星月不相逢 2020-12-30 10:49

I need a little help on an image analysis algorithm in Java. I basically have images like this: \"alt

So

4条回答
  •  遥遥无期
    2020-12-30 11:03

    I've implemented a simple solution (must be improved) using Marvin Framework that finds the vertical lines start and end points and prints the total number of lines found.

    Approach:

    1. Binarize the image using a given threshold.
    2. For each pixel, if it is black (solid), try to find a vertical line
    3. Save the x,y, of the start and end points
    4. The line has a minimum lenght? It is an acceptable line!
    5. Print the start point in red and the end point in green.

    The output image is shown below:

    enter image description here

    The programs output:

    Vertical line fount at: (74,9,70,33)
    Vertical line fount at: (113,9,109,31)
    Vertical line fount at: (80,10,76,32)
    Vertical line fount at: (137,11,133,33)
    Vertical line fount at: (163,11,159,33)
    Vertical line fount at: (184,11,180,33)
    Vertical line fount at: (203,11,199,33)
    Vertical line fount at: (228,11,224,33)
    Vertical line fount at: (248,11,244,33)
    Vertical line fount at: (52,12,50,33)
    Vertical line fount at: (145,13,141,35)
    Vertical line fount at: (173,13,169,35)
    Vertical line fount at: (211,13,207,35)
    Vertical line fount at: (94,14,90,36)
    Vertical line fount at: (238,14,236,35)
    Vertical line fount at: (130,16,128,37)
    Vertical line fount at: (195,16,193,37)
    Vertical lines total: 17
    

    Finally, the source code:

    import java.awt.Color;
    import java.awt.Point;
    import marvin.image.MarvinImage;
    import marvin.io.MarvinImageIO;
    import marvin.plugin.MarvinImagePlugin;
    import marvin.util.MarvinPluginLoader;
    
    public class VerticalLineCounter {
    
        private MarvinImagePlugin threshold = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.color.thresholding");
    
        public VerticalLineCounter(){
            // Binarize
            MarvinImage image = MarvinImageIO.loadImage("./res/lines.jpg");
            MarvinImage binImage = image.clone();
            threshold.setAttribute("threshold", 127);
            threshold.process(image, binImage);
    
            // Find lines and save an output image
            MarvinImage imageOut = findVerticalLines(binImage, image);
            MarvinImageIO.saveImage(imageOut, "./res/lines_out.png");
        }
    
        private MarvinImage findVerticalLines(MarvinImage binImage, MarvinImage originalImage){
            MarvinImage imageOut = originalImage.clone();
            boolean[][] processedPixels = new boolean[binImage.getWidth()][binImage.getHeight()];
            int color;
            Point endPoint;
            int totalLines=0;
            for(int y=0; y 5 || endPoint.y - y > 5){
                                imageOut.fillRect(x-2, y-2, 5, 5, Color.red);
                                imageOut.fillRect(endPoint.x-2, endPoint.y-2, 5, 5, Color.green);
                                totalLines++;
                                System.out.println("Vertical line fount at: ("+x+","+y+","+endPoint.x+","+endPoint.y+")");
                            }
                        }
                    }
                    processedPixels[x][y] = true;
                }
            }
            System.out.println("Vertical lines total: "+totalLines);
            return imageOut;
        }
    
        private Point getEndOfLine(int x, int y, MarvinImage image, boolean[][] processedPixels){
            int xC=x;
            int cY=y;
            while(true){
                processedPixels[xC][cY] = true;
                processedPixels[xC-1][cY] = true;
                processedPixels[xC-2][cY] = true;
                processedPixels[xC-3][cY] = true;
                processedPixels[xC+1][cY] = true;
                processedPixels[xC+2][cY] = true;
                processedPixels[xC+3][cY] = true;
    
                if(getSafeIntColor(xC,cY,image)  < 0xFF000000){
                    // nothing
                }
                else if(getSafeIntColor(xC-1,cY,image) == 0xFF000000){
                    xC = xC-2;
                }
                else if(getSafeIntColor(xC-2,cY,image) == 0xFF000000){
                    xC = xC-3;
                }
                else if(getSafeIntColor(xC+1,cY,image)  == 0xFF000000){ 
                    xC = xC+2;
                }
                else if(getSafeIntColor(xC+2,cY,image)  == 0xFF000000){ 
                    xC = xC+3;
                }
                else{
                    return new Point(xC, cY);
                }
                cY++;
            }
        }
        private int getSafeIntColor(int x, int y, MarvinImage image){
            if(x >= 0 && x < image.getWidth() && y >= 0 && y < image.getHeight()){
                return image.getIntColor(x, y);
            }
            return -1;
        }
        public static void main(String args[]){
            new VerticalLineCounter();
            System.exit(0);
        }
    }
    

提交回复
热议问题