我需要在位图/图像中提取红色/绿色像素,但我不知道该怎么做。 使用OpenCV是一个选择,但我不知道如何使用它,此外它会增加我的应用程序的大小,所以我更喜欢一段代码或其他较轻的库来做到这一点。'由上下文的方式是android。
更新
这是我目前使用的代码,但它并不好,我想要更自动化的内容。
public int getDominantColor(Bitmap bitmap,int RGB_SELECTOR, int Rval, int Gval, int Bval) {//RGB_SELECTOR => 0==getting red colors and 1==getting green color
if (null == bitmap) return Color.TRANSPARENT;
//Log.e("func called with",Integer.toString(RGB_SELECTOR));
int redBucket = 0;
int greenBucket = 0;
int blueBucket = 0;
int alphaBucket = 0;
boolean hasAlpha = bitmap.hasAlpha();
int pixelCount = bitmap.getWidth() * bitmap.getHeight();
int[] pixels = new int[pixelCount];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
int true_pixels_count = 0;
for (int y = 0, h = bitmap.getHeight(); y < h; y++)
{
for (int x = 0, w = bitmap.getWidth(); x < w; x++)
{
int color = pixels[x + y * w]; // x + y * width
if(RGB_SELECTOR == 0 && ((color >> 16) & 0xFF)>Rval &&
((color >> 8) & 0xFF)<Gval && ((color & 0xFF))<Bval){//R
redBucket += (color >> 16) & 0xFF; // Color.red
greenBucket += (color >> 8) & 0xFF; // Color.green
blueBucket += (color & 0xFF); // Color.blue
if (hasAlpha) alphaBucket += (color >>> 24); // Color.alpha
true_pixels_count++;
}else if(RGB_SELECTOR == 1 && (((color >> 16) & 0xFF)<Rval &&
((color >> 8) & 0xFF)>Gval && ((color & 0xFF))<Bval) ||
(((color >> 16) & 0xFF)<0x96 &&
((color >> 8) & 0xFF)>0xBE && ((color & 0xFF))<0x14)){//G
redBucket += (color >> 16) & 0xFF; // Color.red
greenBucket += (color >> 8) & 0xFF; // Color.green
blueBucket += (color & 0xFF); // Color.blue
if (hasAlpha) alphaBucket += (color >>> 24); // Color.alpha
true_pixels_count++;
}else if(RGB_SELECTOR == 2 && ((color >> 16) & 0xFF)<Rval &&
((color >> 8) & 0xFF)<Gval && ((color & 0xFF))>Bval) {//B
redBucket += (color >> 16) & 0xFF; // Color.red
greenBucket += (color >> 8) & 0xFF; // Color.green
blueBucket += (color & 0xFF); // Color.blue
if (hasAlpha) alphaBucket += (color >>> 24); // Color.alpha
true_pixels_count++;
}
else {
bitmap.setPixel(x,y,Color.WHITE);
}
}
}
//Log.e("func ended with",Integer.toString(RGB_SELECTOR));
return Color.argb(
(hasAlpha) ? (alphaBucket / true_pixels_count) : 255,
redBucket / true_pixels_count,
greenBucket / true_pixels_count,
blueBucket / true_pixels_count);
}
答案 0 :(得分:2)
您可以使用
打开位图Bitmap img = BitmapFactory.decodeFile("path/to/img.jpg");
然后,您可以使用
int pixel = img.getPixel(x,y);
并提取特定的RGB值
int red = Color.red(pixel);
int green = Color.green(pixel);
然后,您可以循环显示像素,检查您感兴趣的值,以及当值不是“绿色足够”时,您可以将像素的值设置为例如。白色(这不是测试,只是从记忆中写的)
for (int row = 0; row < img.getWidth(); row++) {
for (int col = 0; col < img.getHeight(); row++) {
// Use the previous functions to get the
// color you are interested in.
int interestingColor = getMyColor(row, col);
// Check if the color is within certain
// range that is "acceptable". If not,
// make it white.
if(!isInRange(interestingColor))
img.setPixel(row, col, Color.WHITE);
}
}
然后,您可以检查边缘开始的位置,并仅提取图像的该部分。
如果您需要更复杂的东西,您可能会重新考虑使用OpenCV。还有例如这一个http://libccv.org/。但是,之前我没有使用它,所以我不能说它是否完全符合您的要求。
答案 1 :(得分:0)
您可以使用Bitmap中的两种方法。
答案 2 :(得分:0)
考虑到我的背景是黑色的,我提出这种方法希望它适用于其他人(因为它是基于java的,它不是那么有效所以你应该考虑在处理之前压缩图像):
public int getDominantColor(Bitmap bitmap) {//gets dominiant color and filters image at the same time
if (null == bitmap) return Color.TRANSPARENT;
final int recognitionThreshold = 0x30;
int redBucket = 0;
int greenBucket = 0;
int blueBucket = 0;
int alphaBucket = 0;
boolean hasAlpha = bitmap.hasAlpha();
int pixelCount = bitmap.getWidth() * bitmap.getHeight();
int[] pixels = new int[pixelCount];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
pixelCount = 0;
float[] hsl = new float[3];
for (int y = 0, h = bitmap.getHeight(); y < h; y++)
{
for (int x = 0, w = bitmap.getWidth(); x < w; x++)
{
int color = pixels[x + y * w]; // x + y * width
Color.colorToHSV(color,hsl);
if((hsl[2]>=0.2f && hsl[2]<=0.8f) && ((((color>>16)&0xFF) > recognitionThreshold) ||(((color>>8)&0xFF) > recognitionThreshold))){//you can change Luminiance threshold and green/red threshold for better results but this worked for my case pretty well
redBucket += (color >> 16) & 0xFF; // Color.red
greenBucket += (color >> 8) & 0xFF; // Color.green
blueBucket += (color & 0xFF); // Color.blue
pixelCount++;
if (hasAlpha) alphaBucket += (color >>> 24); // Color.alpha
}else {
//this pixel is not my favorite so I color it to white
bitmap.setPixel(x,y,Color.WHITE);
}
}
}
return Color.argb(
(hasAlpha) ? (alphaBucket / pixelCount) : 255,
redBucket / pixelCount,
greenBucket / pixelCount,
blueBucket / pixelCount);
}