Java 有没有合适的算法来检测人物的背景色?

Java 有没有合适的算法来检测人物的背景色?,java,image,Java,Image,在大学里,我们被分配了一个任务,给我们一张图片,我们必须识别“人物”、他们的颜色以及他们里面的“像素组”的数量。让我解释一下: 上面的图像有一个图(在图像中可以有多个图,但现在让我们先忘掉这一点) 画布的背景色是0,0处的像素(在本例中为黄色) 图形的边框颜色为黑色(可以是画布背景色以外的任何颜色) 人物的背景色为白色(也可以与画布的背景色相同) 图形只能有一种背景色 图中有两个像素组。一个是蓝色像素池,另一个是红色像素池,里面有一些绿色。如您所见,像素组像素的颜色并不重要(它只是与图形的背

在大学里,我们被分配了一个任务,给我们一张图片,我们必须识别“人物”、他们的颜色以及他们里面的“像素组”的数量。让我解释一下:

上面的图像有一个图(在图像中可以有多个图,但现在让我们先忘掉这一点)

  • 画布的背景色是0,0处的像素(在本例中为黄色)
  • 图形的边框颜色为黑色(可以是画布背景色以外的任何颜色)
  • 人物的背景色为白色(也可以与画布的背景色相同)
  • 图形只能有一种背景色
  • 图中有两个像素组。一个是蓝色像素池,另一个是红色像素池,里面有一些绿色。如您所见,像素组像素的颜色并不重要(它只是与图形的背景颜色不同)。重要的是他们彼此接触(甚至是对角线)。所以,尽管有两种不同的颜色,这类人还是被认为是唯一的
  • 正如你所看到的,边界可以像你所希望的那样不规则。然而,它只有一种颜色
  • 众所周知,像素组不会接触边界
  • 我被告知像素组的颜色可以是除图形背景色以外的任何颜色。我假设它可以与图形的边框颜色(黑色)相同
我们得到了一个能够拍摄图像并将其转换为矩阵的类(每个元素都是表示像素颜色的整数)

就这样。我正在用Java做这件事

到目前为止我做了什么

  • 迭代矩阵中的每个像素
  • 如果我发现一个像素与背景颜色不同,我将假定它属于图形的边框。从现在起,我将称这个像素为
    initialPixel
  • 请注意,我提供的图像中的
    initialPixel
    是图左上角的黑色像素。我特意在那里做了一个锐利的切割来说明它
  • 我现在的任务是找到人物的背景色(在本例中为白色)
但是我很难找到这样的背景色(白色)。这是我所做的最接近的方法,在某些情况下有效,但不适用于此图像:

  • 因为我知道边界的颜色,所以我可以找到第一种不同的颜色,即
    initialPixel
    南部。听起来确实是个好主意-它有时确实有效,但与提供的图像不起作用:在本例中,它将返回黄色,因为
    initialPixel
    与图形的内容相差很远
假设我确实找到了图形的背景色(白色),我的下一个任务将是认识到图形中存在两个像素组。这一组似乎更容易:

  • 因为我现在知道了图形的背景色(白色),我可以尝试迭代图形中的每个像素,如果我找到一个不属于边框且不属于图形背景的像素,我就可以知道有一个像素组。我可以开始一个递归函数,找到与这些组相关的所有像素,并“标记”它们,以便在未来的迭代中完全忽略这些像素
我需要什么

是的,我的问题是如何根据我之前描述的找到人物的背景色(请记住,它可以与整个图像的背景色相同-现在它是黄色,但也可以是白色)

我不需要任何代码——我只是想不出适合这种情况的算法。边界上有这么奇怪的不规则线条,这真让我受不了

或者更好:我一直在做错事吗?也许我根本就不应该把太多精力放在
initialPixel
上。也许一种不同的初始方法会奏效?是否有关于此类主题的文档/示例?我意识到有很多关于“计算机视觉”之类的研究,但我找不到很多关于这个特殊问题的资料

一些代码

我的函数用于检索包含所有图形的向量: *注意:
Figure
只是一个类,它包含一些值,如背景色和元素数

public Figure[] getFiguresFromImage(Image image) {
    Figure[] tempFigures = new Figure[100];
    int numberOfFigures = 0;
    matrixOfImage = image.getMatrix();
    int imageBackgroundColor = matrixOfImage[0][0];
    int pixel = 0;

    for (int y = 0; y < matrixOfImage.length; ++y) {
        for (int x = 0; x < matrixOfImage[0].length; ++x) {
            pixel = matrixOfImage[y][x];
            if (!exploredPixels[y][x]) {
                // This pixel has not been evaluated yet
                if (pixel != imageBackgroundColor ) {
                    // This pixel is different than the background color
                    // Since it is a new pixel, I assume it is the initial pixel of a new figure
                    // Get the figure based on the initial pixel found
                    tempFigures[numberOfFigures] = retrieveFigure(y,x);
                    ++numberOfFigures;
                }
            }
        }   
    }

    // ** Do some work here after getting my figures **

    return null;
}
public Figure[]从图像获取图像(图像图像){
图[]临时数字=新数字[100];
int numberOfFigures=0;
matrixOfImage=image.getMatrix();
int imageBackgroundColor=matrixOfImage[0][0];
整数像素=0;
对于(int y=0;y
然后,很明显,函数
retrieveFigure(y,x)
是我无法做到的

注意事项:

  • 出于学习目的,我不应该使用任何外部库
尝试以下代码:

import java.util.Scanner;
import java.awt.image.BufferedImage;
import java.io.*;

import javax.imageio.ImageIO;

class Analyzer{
    private int pixdata[][];
    private int rgbdata[][];
    private BufferedImage image;
    int background_color;
    int border_color;
    int imagebg_color;
    private void populateRGB(){
        rgbdata = new int[image.getWidth()][image.getHeight()];
        for(int i = 0; i < image.getWidth(); i++){
            for(int j = 0; j < image.getHeight(); j++){
                rgbdata[i][j] = image.getRGB(i, j);
            }
        }
        int howmanydone = 0;
        int prevcolor,newcolor;
        prevcolor = rgbdata[0][0];

        /*
        for(int i = 0; i < image.getWidth(); i++){
           for(int j = 0; j < image.getHeight(); j++){
              System.out.print(rgbdata[i][j]);
           }
           System.out.println("");
        }*/
        for(int i = 0; i < image.getWidth(); i++){
            for(int j = 0; j < image.getHeight(); j++){
                newcolor = rgbdata[i][j];
                if((howmanydone == 0) && (newcolor != prevcolor)){
                    background_color = prevcolor;
                    border_color = newcolor;
                    prevcolor = newcolor;
                    howmanydone = 1;
                }
                if((newcolor != prevcolor) && (howmanydone == 1)){
                    imagebg_color = newcolor;
                }
            }
        }
    }
    public Analyzer(){ background_color = 0; border_color = 0; imagebg_color = 0;}
    public int background(){ return background_color; }
    public int border() { return border_color;}
    public int imagebg() {return imagebg_color;}
    public int analyze(String filename,String what) throws IOException{
        image = ImageIO.read(new File(filename));
        pixdata = new int[image.getHeight()][image.getWidth()];
        populateRGB();
        if(what.equals("background"))return background();
        if(what.equals("border"))return border();
        if(what.equals("image-background"))return imagebg();
        else return 0;
    }
}
public class ImageAnalyze{
    public static void main(String[] args){
        Analyzer an = new Analyzer();
        String imageName;

        Scanner scan = new Scanner(System.in);
        System.out.print("Enter image name:");
        imageName = scan.nextLine();
        try{
        int a = an.analyze(imageName,"border");//"border","image-background","background" will get you different colors
        System.out.printf("Color bg: %x",a);

        }catch(Exception e){
           System.out.println(e.getMessage());
        }
    }
}
import java.util.Scanner;
导入java.awt.image.buffereImage;
导入java.io.*;
导入javax.imageio.imageio;
类分析器{
私有int-pixdata[]];
私有int rgbdata[][];
P
List<Component> allComponents; // created in step 2
Component background; // found in step 3 (this is the component with the 0,0 pixel)
Component figureBorder; // found in step 4
List<Component> pixelGroups = new List<Component>(); // list of pixel groups

for each Component c in allComponents:
    if c == background:
        continue;
    for each Pixel pixel in c.pixelList:
        for each Pixel neighbor in pixel.neighbors:
            if neighbor.getComponent() == figureBorder:
                c.isPixelGroup = true;

int numPixelGroups = 0;
for each Component c in allComponents:
    if (c.isPixelGroup)
        numPixelGroups++;