我想知道目前是否有任何用 Java 编写的算法来确定图像中是否包含低范围的不同像素颜色。
我正在尝试检测占位符图像(通常由高百分比的单色(通常是白色和灰色像素)组成,而不是全彩色照片(由多种颜色组成)。
如果什么都不存在,我会自己写一些东西(正在考虑对图像中随机位置的任意像素进行采样,或者对图像中包含的所有像素颜色进行平均),然后确定我找到的不同颜色的数量。根据所使用的方法,速度和准确性之间可能存在折衷。
任何建议/指针/阅读材料表示赞赏。
一种简单的低开销方法是分别制作红色、绿色和蓝色分量值的直方图。每个只有 256 个颜色级别,所以它会非常有效 - 您可以在new int[256]
数组中构建每个直方图。
然后您只需计算每个直方图中非零值的数量并检查它们是否都满足某个阈值(例如,每个直方图中至少有 20 个不同的值意味着一张照片)
另一种方法是在图像中创建颜色值的 HashSet,并在扫描图像时不断添加到 HashSet。由于 HashSets 拥有唯一的值,它只会存储唯一的颜色。为避免 HashSet 变得太大,您可以在 HashSet 的大小达到预先确定的阈值(可能是 1000 种不同的颜色?)时退出,并得出您有照片的结论。
一种方法是:
final BufferedImage image = // your image;
final Set<Integer> colours = new HashSet<Integer>();
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
colours.add(image.getRGB(x, y));
}
}
// Check your pixels here. In grayscale images the R equals G equals B
您还可以使用 Java Advanced Imaging (JAI),因为它提供了一个直方图类:
package com.datroop.histogram;
import java.awt.image.renderable.ParameterBlock;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import javax.media.jai.Histogram;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.ROI;
import javax.media.jai.RenderedOp;
public class HistogramCreator {
private HistogramCreator() {
}
public static int[] createHistogram(final PlanarImage image) {
// set up the histogram
final int[] bins = { 256 };
final double[] low = { 0.0D };
final double[] high = { 256.0D };
Histogram histogram = new Histogram(bins, low, high);
final ParameterBlock pb = new ParameterBlock();
pb.addSource(image);
pb.add(null);
pb.add(1);
pb.add(1);
final RenderedOp op = JAI.create("histogram", pb);
histogram = (Histogram) op.getProperty("histogram");
// get histogram contents
final int[] local_array = new int[histogram.getNumBins(0)];
for (int i = 0; i < histogram.getNumBins(0); i++) {
local_array[i] = histogram.getBinSize(0, i);
}
return local_array;
}
public static void main(String[] args) {
try {
String filename = "file://localhost/C:/myimage.jpg";
System.setProperty("com.sun.media.jai.disableMediaLib", "true");
// Create the histogram
int[] myHistogram = createHistogram(JAI.create("url", new URL(filename)));
// Check it out here
System.out.println(Arrays.toString(myHistogram));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}