在图片中找到美国国旗?

2 浏览
0 Comments

在图片中找到美国国旗?

为庆祝美国独立日,我对找到一种程序化方法来检测图片中的美国国旗很感兴趣。有一个早期且受欢迎的问题涉及在图像中寻找可口可乐罐,它描述了解决该问题的许多好技术,尽管我不确定它们是否适用于国旗,因为:1. 国旗在风中飘扬,因此可能遮挡自己或以非线性方式变形(这使得像SIFT这样的技术有点难以使用)。2. 与可口可乐罐不同,美国国旗的星条旗不是美国国旗独有的,可以是利比里亚的国旗的一部分,排除了许多“线条特征”技术。有没有任何标准的图像处理或识别技术可以特别适用于这个任务?

admin 更改状态以发布 2023年5月21日
0
0 Comments

你可以使用OpenCV库中的“模板匹配”。

这是方法背后的理论:

模板匹配是一种方法,用于在较大的图像中搜索和查找模板图像的位置。OpenCV带有一个名为cv2.matchTemplate()的函数来实现此目的。它只是滑动模板图像覆盖输入图像(如二维卷积)并比较模板和模板图像下的输入图像的补丁。

可以在此处找到代码示例和实现解释:http://docs.opencv.org/master/d4/dc6/tutorial_py_template_matching.html#gsc.tab=0

0
0 Comments

我的方法将问题推广,并寻找靠近蓝色区域的红白条纹(水平或垂直)模式,因此该方法适用于仅有美国国旗具有该模式的情景。\n\n我的方法用Java开发,使用Marvin Framework。\n\n算法:\n\n1. 颜色过滤器,保留仅为美国国旗的颜色的像素\n2. 查找水平的红白条纹模式\n3. 查找垂直的红白条纹模式\n4. 去除小面积模式(噪声)\n5. 检查该模式是否被蓝色区域包围\n6. 对该区域进行分割\n\n输入:\n\n图片链接\n\n颜色过滤:\n\n图片链接\n\n国旗:\n\n图片链接\n\n当有许多国旗时,表现更加有趣。\n\n输入:\n\n图片链接\n\n颜色过滤:\n\n图片链接\n\n模式匹配:\n\n图片链接\n\n国旗:\n\n图片链接\n\n源代码:\n\n

import static marvin.MarvinPluginCollection.*;
public class AmericanFlag {
    public AmericanFlag(){
        process("./res/flags/", "flag_0", Color.yellow);
        process("./res/flags/", "flag_1", Color.yellow);
        process("./res/flags/", "flag_2", Color.yellow);
        process("./res/flags/", "flag_3", Color.yellow);
        process("./res/flags/", "flag_4", Color.blue);
    }
    private void process(String dir, String fileName, Color color){
        MarvinImage originalImage = MarvinImageIO.loadImage(dir+fileName+".jpg");
        MarvinImage image = originalImage.clone();
        colorFilter(image);
        MarvinImageIO.saveImage(image, dir+fileName+"_color.png");
        MarvinImage output = new MarvinImage(image.getWidth(), image.getHeight());
        output.clear(0xFFFFFFFF);
        findStripsH(image, output);
        findStripsV(image, output);
        MarvinImageIO.saveImage(output, dir+fileName+"_1.png");
        MarvinImage bin = MarvinColorModelConverter.rgbToBinary(output, 127);
        morphologicalErosion(bin.clone(), bin, MarvinMath.getTrueMatrix(5, 5));
        morphologicalDilation(bin.clone(), bin, MarvinMath.getTrueMatrix(15, 15));
        MarvinImageIO.saveImage(bin, dir+fileName+"_2.png");
        int[] centroid = getCentroid(bin);
        image.fillRect(centroid[0], centroid[1], 30, 30, Color.yellow);
        int area = getMass(bin);
        boolean blueNeighbors = hasBlueNeighbors(image, bin, centroid[0], centroid[1], area);
        if(blueNeighbors){
            int[] seg = getSegment(bin);
            for(int i=0; i<4; i++){
                originalImage.drawRect(seg[0]+i, seg[1]+i, seg[2]-seg[0], seg[3]-seg[1], color);
            }
            MarvinImageIO.saveImage(originalImage, dir+fileName+"_final.png");
        }
    }
    private boolean hasBlueNeighbors(MarvinImage image, MarvinImage bin, int centerX, int centerY, int area){
        int totalBlue=0;
        int r,g,b;
        int maxDistance =  (int)(Math.sqrt(area)*1.2);
        for(int y=0; y area/5){
            return true;
        }
        return false;
    }
    private int[] getCentroid(MarvinImage bin){
        long totalX=0, totalY=0, totalPixels=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,y2};
    }
    private void findStripsH(MarvinImage imageIn, MarvinImage imageOut){
        int strips=0;
        int totalPixels=0;
        int r,g,b;
        int patternStart;
        boolean cR=true;
        int patternLength = -1;
        for(int y=0; y=3 && totalPixels <= 100){
                                patternLength = (int)(totalPixels);
                            } else{
                                totalPixels=0; patternStart=-1; strips=0; patternLength=-1;
                            }
                        } else{
                            if(totalPixels >= Math.max(patternLength*0.5,3) && totalPixels <= patternLength * 2){
                                strips++;
                                totalPixels=1;
                                cR = false;
                            } else{
                                totalPixels=0; patternStart=-1; strips=0; patternLength=-1;
                            }
                        }
                    }
                }
                else{
                    if(r == 255 && g == 255 && b == 255){
                        totalPixels++;
                    } else{
                        if(totalPixels >= Math.max(patternLength*0.5,3) && totalPixels <= patternLength * 2){
                            strips++;
                            totalPixels=1;
                            cR = true;
                        } else{
                            totalPixels=0; patternStart=-1; strips=0; patternLength=-1; cR=true;
                        }
                    }
                }
                if(strips >= 4){
                    imageOut.fillRect(patternStart, y, x-patternStart, 2, Color.black);
                    totalPixels=0; patternStart=-1; strips=0; patternLength=-1; cR=true;
                }
            }
        }
    }
    private void findStripsV(MarvinImage imageIn, MarvinImage imageOut){
        int strips=0;
        int totalPixels=0;
        int r,g,b;
        int patternStart;
        boolean cR=true;
        int patternLength = -1;
        for(int x=0; x=3 && totalPixels <= 100){
                                patternLength = (int)(totalPixels);
                            } else{
                                totalPixels=0; patternStart=-1; strips=0; patternLength=-1;
                            }
                        } else{
                            if(totalPixels >= Math.max(patternLength*0.5,3) && totalPixels <= patternLength * 2){
                                strips++;
                                totalPixels=1;
                                cR = false;
                            } else{
                                totalPixels=0; patternStart=-1; strips=0; patternLength=-1;
                            }
                        }
                    }
//                  if(maxL != -1 && totalPixels > maxL){
//                      totalPixels=0; patternStart=-1; strips=0; maxL=-1;
//                  }
                }
                else{
                    if(r == 255 && g == 255 && b == 255){
                        totalPixels++;
                    } else{
                        if(totalPixels >= Math.max(patternLength*0.5,3) && totalPixels <= patternLength * 2){
                            strips++;
                            totalPixels=1;
                            cR = true;
                        } else{
                            totalPixels=0; patternStart=-1; strips=0; patternLength=-1; cR=true;
                        }
                    }
//                  if(maxL != -1 &&  totalPixels > maxL){
//                      totalPixels=0; patternStart=-1; strips=0; maxL=-1;
//                      cR=true;
//                  }
                }
                if(strips >= 4){
                    imageOut.fillRect(x, patternStart, 2, y-patternStart, Color.black);
                    totalPixels=0; patternStart=-1; strips=0; patternLength=-1; cR=true;
                }
            }
        }
    }
    private void colorFilter(MarvinImage image){
        int r,g,b;
        boolean isR, isB;
        for(int y=0; y 120 && r > g * 1.3 && r > b * 1.3);
                isB = (b > 30 && b < 150 && b > r * 1.3 && b > g * 1.3);
                if(isR){
                    image.setIntColor(x, y, 255,0,0);
                } else if(isB){
                    image.setIntColor(x, y, 0,0,255);
                } else{
                    image.setIntColor(x, y, 255,255,255);
                }
            }
        }
    }
    public static void main(String[] args) {
        new AmericanFlag();
    }
}

\n\n其他结果:\n\n图片链接\n\n图片链接\n\n图片链接

0