检测单个图像中的多个图像

我需要帮助来识别边框并将图像与原始图像进行比较。 我需要指导如何通过处理或matlab或任何初学者来实现这一点。 例如看下面的图片。

原始图像:

在这里输入图像描述

多重形象: 放大图像


你展示的“多重图像”很容易处理,只需使用简单的图像处理,无需模板匹配:)

% read the second image
img2 = imread('http://i.stack.imgur.com/zyHuj.jpg');
img2 = im2double(rgb2gray(img2));

% detect coca-cola logos
bw = im2bw(img2);                                       % Otsu's thresholding
bw = imfill(~bw, 'holes');                              % fill holes
stats = regionprops(bw, {'Centroid', 'BoundingBox'});   % connected components

% show centers and bounding boxes of each connected component
centers = vertcat(stats.Centroid);
imshow(img2), hold on
plot(centers(:,1), centers(:,2), 'LineStyle','none', ...
    'Marker','x', 'MarkerSize',20, 'Color','r', 'LineWidth',3)
for i=1:numel(stats)
    rectangle('Position',stats(i).BoundingBox, ...
        'EdgeColor','g', 'LineWidth',3)
end
hold off

在这里输入图像描述


您可以使用相关性方法来定位多个图像:

file1='http://i.stack.imgur.com/1KyJA.jpg';
file2='http://i.stack.imgur.com/zyHuj.jpg';
It = imread(file1);
Ii = imread(file2);
It=rgb2gray(It);
Ii=rgb2gray(Ii);
It=double(It);  % template
Ii=double(Ii);  % image

Ii_mean = conv2(Ii,ones(size(It))./numel(It),'same');
It_mean = mean(It(:));
corr_1 = conv2(Ii,rot90(It-It_mean,2),'same')./numel(It);
corr_2 = Ii_mean.*sum(It(:)-It_mean);
conv_std = sqrt(conv2(Ii.^2,ones(size(It))./numel(It),'same')-Ii_mean.^2);
It_std = std(It(:));
S = (corr_1-corr_2)./(conv_std.*It_std);

imagesc(abs(S))

结果将为您提供最大值的职位:

在这里输入图像描述

获取最大值的坐标,并将模板质心定位在同一位置,检查模板和匹配图像之间的差异。

我不确定“确定边界”是什么意思,但你总是可以用Canny检测器提取边缘:

bw=edge(It);
bw=imfill(bw,'holes');
figure,imshow(bw)

下面介绍一个使用Marvin图像处理框架在Java中实现的解决方案。

做法:

  • 在“原始图像”中加载,分割和缩放(50x50)徽标。
  • 在“多个图像”中加载,分段和缩放(50x50)每个徽标
  • 对于“多图像”中的每个标识,与“原始图像”中的标识进行比较。 如果几乎相同,请绘制矩形以突出显示。
  • 比较方法(内差异插件):

    对于两个徽标中的每个像素,请比较每个颜色分量。 如果一个颜色分量的差异高于给定的阈值,则认为这两个标识的像素不同。 计算不同像素的总数。 如果两个徽标有多个不同的像素高于另一个阈值,则认为它们不同。 重要提示:这种方法对旋转和透视变化非常敏感。

    由于您的样本(“多图像”)只有古柯徽标,所以我冒昧地加入另一个徽标以声明该算法。

    多重图像2

    在这里输入图像描述

    产量

    在这里输入图像描述

    在另一项测试中,我包含了另外两个类似的古柯标志。 通过更改阈值参数,您可以指定是否需要完全相同的徽标或接受其变体。 在下面的结果中,参数被设置为接受标志变化。

    多重图像3

    在这里输入图像描述

    产量

    在这里输入图像描述

    源代码

    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<Integer> 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<subimages.length; i++){
            diff.setAttribute("comparisonImage", subimages[i]);
            diff.setAttribute("colorRange", 30);
            diff.process(target, null, attrOut);
            if((Integer)attrOut.get("total") < (50*50)*0.6){
                original.drawRect(rects[i][0], rects[i][6], rects[i][7], rects[i][8], 6, Color.green);
            }
        }
    }
    
    private MarvinImage segmentTarget(){
        MarvinImage original = MarvinImageIO.loadImage("./res/logos/target.jpg");
        MarvinImage target = original.clone();
        threshold.process(target, target);
        MarvinImage image2 = new MarvinImage(target.getWidth(), target.getHeight());
        fill(target, image2);
        LinkedHashSet<Integer> objects = filterByMass(image2, 10000);
        int[][] rects = getRects(objects, image2, target);
        MarvinImage[] subimages = getSubimages(rects, original);
        return subimages[0];
    }
    
    
    
    private int[][] getRects(LinkedHashSet<Integer> objects, MarvinImage mask, MarvinImage original){
        List<int[]> ret = new ArrayList<int[]>();
        for(Integer color:objects){
            ret.add(getObjectRect(mask, color));
        }
        return ret.toArray(new int[0][0]);
    }
    
    private MarvinImage[] getSubimages(int[][] rects, MarvinImage original){
        List<MarvinImage> ret = new ArrayList<MarvinImage>();
        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<imageIn.getHeight(); y++){
                for(int x=0; x<imageIn.getWidth(); x++){
                    if(imageOut.getIntColor(x,y) == 0 && imageIn.getIntColor(x, y) != 0xFFFFFFFF){
                        fill.setAttribute("x", x);
                        fill.setAttribute("y", y);
                        fill.setAttribute("color", color);
                        fill.setAttribute("threshold", 120);
                        fill.process(imageIn, imageOut);
                        color = newColor(color);
    
                        found = true;
                        break Outerloop;
                    }
                }
            }
    
            if(!found){
                break;
            }
        }
    }
    
    private LinkedHashSet<Integer> filterByMass(MarvinImage image, int mass){
        boolean found;
        HashSet<Integer> analysed = new HashSet<Integer>();
        LinkedHashSet<Integer> ret = new LinkedHashSet<Integer>();
    
        while(true){
            found=false;
    
            outerLoop:
            for(int y=0; y<image.getHeight(); y++){
                for(int x=0; x<image.getWidth(); x++){
                    int color = image.getIntColor(x,y); 
                    if(color != 0){
                        if(!analysed.contains(color)){
                            if(getMass(image, color) >= 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<image.getHeight(); y++){
            for(int x=0; x<image.getWidth(); x++){
                if(image.getIntColor(x, y) == color){
                    total++;
                }
            }
        }
        return total;
    }
    
    private int[] getObjectRect(MarvinImage mask, int color){
        int x1=-1;
        int x2=-1;
        int y1=-1;
        int y2=-1;
    
        for(int y=0; y<mask.getHeight(); y++){
            for(int x=0; x<mask.getWidth(); x++){
                if(mask.getIntColor(x, y) == color){
    
                    if(x1 == -1 || x < x1){
                        x1 = x;
                    }
                    if(x2 == -1 || x > 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();
    }   
    }
    
    链接地址: http://www.djcxy.com/p/79567.html

    上一篇: Detecting multiple images in a single image

    下一篇: Image Processing: Algorithm Improvement for 'Coca