Detecting multiple images in a single image

后端 未结 6 1653
滥情空心
滥情空心 2021-01-30 21:39

I need help to identify the border and compare the images with the original image. I need guidance on How can I achieve this through processing or matlab or anything for beginne

6条回答
  •  天命终不由人
    2021-01-30 22:22

    Below is presented a solution implemented in Java, using Marvin image processing framework.

    Approach:

    1. Load, segment and scale (50x50) the logo in the "original image".
    2. Load, segment and scale (50x50) each logo in the "multiple image"
    3. For each logo in "mulitple image", compare with the logo in "original image". If it is almost the same, draw a rect to highlight.

    Comparison method (inside diff plug-in):

    For each pixel in two logos, compare each color component. If the difference in one color component is higher then a given threshold, consider that pixel different for the two logos. Compute the total number of different pixels. If two logos have a number of different pixels higher than another threshold, consider them different. IMPORTANT: This approach is very sensitive to rotation and perspective variation.

    Since your sample ("multiple image") has only coca logos, I took the liberty to include another logo in order to assert the algorithm.

    The Multiple Image 2

    enter image description here

    Output

    enter image description here

    In another test, I've included two another similar coca logos. Changing the threshold parameters you can specify whether you want the exact same logo or accept its variations. In the result below, the parameters were set to accept logo variations.

    The Multiple Image 3

    enter image description here

    Output

    enter image description here

    Source code

    public class Logos {
    
    private MarvinImagePlugin threshold = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.color.thresholding");
    private MarvinImagePlugin fill = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.fill.boundaryFill");
    private MarvinImagePlugin scale = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.transform.scale");
    private MarvinImagePlugin diff = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.difference.differenceColor");
    
    public Logos(){
    
        // 1. Load, segment and scale the object to be found
        MarvinImage target = segmentTarget();
    
        // 2. Load the image with multiple objects
        MarvinImage original = MarvinImageIO.loadImage("./res/logos/logos.jpg");
        MarvinImage image = original.clone();
    
        // 3. Segment
        threshold.process(image, image);
        MarvinImage image2 = new MarvinImage(image.getWidth(), image.getHeight());
        fill(image, image2);
        MarvinImageIO.saveImage(image2, "./res/logos/logos_fill.jpg");
    
        // 4. Filter segments by its their masses
        LinkedHashSet objects = filterByMass(image2, 10000);
        int[][] rects = getRects(objects, image2, original);
        MarvinImage[] subimages = getSubimages(rects, original);
    
        // 5. Compare the target object with each object in the other image
        compare(target, subimages, original, rects);
        MarvinImageIO.saveImage(original, "./res/logos/logos_out.jpg");
    }
    
    private void compare(MarvinImage target, MarvinImage[] subimages, MarvinImage original, int[][] rects){
        MarvinAttributes attrOut = new MarvinAttributes();
        for(int i=0; i objects = filterByMass(image2, 10000);
        int[][] rects = getRects(objects, image2, target);
        MarvinImage[] subimages = getSubimages(rects, original);
        return subimages[0];
    }
    
    
    
    private int[][] getRects(LinkedHashSet objects, MarvinImage mask, MarvinImage original){
        List ret = new ArrayList();
        for(Integer color:objects){
            ret.add(getObjectRect(mask, color));
        }
        return ret.toArray(new int[0][0]);
    }
    
    private MarvinImage[] getSubimages(int[][] rects, MarvinImage original){
        List ret = new ArrayList();
        for(int[] r:rects){
            ret.add(getSubimage(r, original));
        }
        return ret.toArray(new MarvinImage[0]);
    }
    
    private MarvinImage getSubimage(int rect[], MarvinImage original){
        MarvinImage img = original.subimage(rect[0], rect[1], rect[2], rect[3]);
        MarvinImage ret = new MarvinImage(50,50);
        scale.setAttribute("newWidth", 50);
        scale.setAttribute("newHeight", 50);
        scale.process(img, ret);
        return ret;
    }
    
    private void fill(MarvinImage imageIn, MarvinImage imageOut){
        boolean found;
        int color= 0xFFFF0000;
    
        while(true){
            found=false;
    
            Outerloop:
            for(int y=0; y filterByMass(MarvinImage image, int mass){
        boolean found;
        HashSet analysed = new HashSet();
        LinkedHashSet ret = new LinkedHashSet();
    
        while(true){
            found=false;
    
            outerLoop:
            for(int y=0; y= mass){
                                ret.add(color); 
                            }
                            analysed.add(color);
                            found = true;
                            break outerLoop;
                        }
                    }
                }
            }
    
            if(!found){
                break;
            }
        }
        return ret;
    }
    
    private int getMass(MarvinImage image, int color){
        int total=0;
        for(int y=0; y x2){
                        x2 = x;
                    }
                    if(y1 == -1 || y < y1){
                        y1 = y;
                    }
                    if(y2 == -1 || y > y2){
                        y2 = y;
                    }
                }
            }
        }
    
        return new int[]{x1, y1, (x2-x1), (y2-y1)};
    }
    
    private int newColor(int color){
        int red = (color & 0x00FF0000) >> 16;
        int green = (color & 0x0000FF00) >> 8;
        int blue = (color & 0x000000FF);
    
        if(red <= green && red <= blue){
            red+=5;
        }
        else if(green <= red && green <= blue){
            green+=5;
        }
        else{
            blue+=5;
        }
    
        return 0xFF000000 + (red << 16) + (green << 8) + blue;
    }
    
    public static void main(String[] args) {
        new Logos();
    }   
    }
    

提交回复
热议问题