以下代码是检测动作并保存预览的工作相机应用程序的一部分,将运动部件涂成红色。
public class RgbMotionDetection implements IMotionDetection {
that detects motion
private static final int mPixelThreshold = 50; // Difference in pixel (RGB)
private static final int mThreshold = 10000; // Number of different pixels
private static int[] mPrevious = null;
private static int mPreviousWidth = 0;
private static int mPreviousHeight = 0;
/**
* {@inheritDoc}
*/
@Override
public int[] getPrevious() {
return ((mPrevious != null) ? mPrevious.clone() : null);
}
protected static boolean isDifferent(int[] first, int width, int height) {
if (first == null) throw new NullPointerException();
if (mPrevious == null) return false;
if (first.length != mPrevious.length) return true;
if (mPreviousWidth != width || mPreviousHeight != height) return true;
int totDifferentPixels = 0;
for (int i = 0, ij = 0; i < height; i++) {
for (int j = 0; j < width; j++, ij++) {
int pix = (0xff & ((int) first[ij]));
int otherPix = (0xff & ((int) mPrevious[ij]));
// Catch any pixels that are out of range
if (pix < 0) pix = 0;
if (pix > 255) pix = 255;
if (otherPix < 0) otherPix = 0;
if (otherPix > 255) otherPix = 255;
if (Math.abs(pix - otherPix) >= mPixelThreshold) {
totDifferentPixels++;
// Paint different pixel red
first[ij] = Color.RED;
}
}
}
我想完全理解这一点,以便能够修改。
让我感到困惑的是:
int pix = (0xff & ((int) first[ij]));
它做了什么?
感谢
戴夫
答案 0 :(得分:1)
我认为在这里尝试获取像素的值但在0到255的范围内,因此它使用掩码0xFF来删除比8更高位置的所有位。
但我不明白为什么会使用
if (pix < 0) pix = 0;
if (pix > 255) pix = 255;
当pix变量不能高于255时
答案 1 :(得分:1)
原谅我,如果我现在解释一些你知道的东西,但我想把它作为一个独立的答案。
像素的颜色可以存储在整数中。 Java中的整数由四个字节组成,颜色通常(在此上下文中)用四个字节表示:红色,绿色和蓝色各一个字节,透明度的最后一个字节。屏幕上的子像素混合会产生观察到的颜色。
所以下面的整数代表一种颜色:
0 0 f f c c a a (Hexadecimal representation)
0000 0000 1111 1111 1100 1100 1010 1010 (Binary representation)
Transp.-- Red------ Green---- Blue----- (Color interpretation)
16764074 (Decimal representation, quite useless here)
在这种情况下,前两个字节(00)代表透明度,ff为红色子像素,cc为绿色,aa为蓝色。
如果我们想要只获得其中的一部分,例如蓝色子像素,我们需要一点掩码。
0000 0000 1111 1111 1100 1100 1010 1010 (Binary representation)
& (Binary AND: Return 1 if both bits are 1)
0000 0000 0000 0000 0000 0000 1111 1111 (Bitmask for blue, in hex 0x000000ff)
=
0000 0000 0000 0000 0000 0000 1010 1010
这是您提到的行中操作的结果,它只是使用掩码的简写十六进制解释:
int pix = (0xff & ((int) first[ij]));
由于数组first
已经是int
数组,first[ij]
的强制转换是无用的。
如果您想要像素的另一部分,比如绿色部分,则需要移动蒙版(或使用硬编码值)并需要移回结果:
00ffccaa
&
0000ff00 Hardcoded, alternative: ff << 8
=
0000cc00
将结果移至整数
中的最右侧位置0000cc00 >> 8 = 000000cc
类似于红色和16和24。透明度。
因此该行为您提供像素的蓝色子像素的值。该值在0..255的范围内,因为这些是8位可能的唯一值(当解释为无符号字节或存储在Java int
中时,如此处所做的那样; Java byte
s已签名,不会使用该十进制表示,但-128..127);任何检查其他值都没用。