这几天在群里吹牛逼的时候,遇到群友的一个提问,大概是水表上的4个指针识别角度,如图所示:
思路是水表都是固定状态 所以遮挡个蒙版 想办法让用户对准固定的 位置 拍照 这样方便取出单独的小框框 如图所示:
这样可以单独取出框内进行红色提取 在进行边缘判定后根据边缘坐标判断中心点。。结果肯定是中心到 连接线最远的边界点就是方向所在的位置了。。
代码如下:
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
YuvImage image = new YuvImage(data, ImageFormat.NV21, 1920, 1080, null);
if (image != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, 1920, 1080), 100, stream);
BitmapFactory.Options options = new BitmapFactory.Options();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
options.outConfig = Bitmap.Config.RGB_565;
}
Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size(), options);
Bitmap bm = Bitmap.createBitmap(bmp, bmp.getWidth() / 2 - 100,
bmp.getHeight() / 2 - 100, 200,
200, null, true);
int sum = 0;
int left = 0;
int top = 0;
int right = 0;
int bottom = 0;
boolean leftFirst = false;
for (int i = 0; i < bm.getWidth(); i++) {
for (int k = 0; k < bm.getHeight(); k++) {
int color = bm.getPixel(i, k);
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
if ((
(((hsv[0] / 2 >= 0f) && (hsv[0] / 2 <= 10f))
||
((hsv[0] / 2 >= 156f) && (hsv[0] / 2 <= 180f))))
&& (hsv[1] * 255 >= 43 && hsv[1] * 255 <= 255)
&& (hsv[2] * 255 >= 46 && hsv[2] * 255 <= 255)
) {
sum++;//红色判定
if (!leftFirst) {
leftFirst = true;
left = i;
}
right = i;
} else {
bm.setPixel(i, k, 0);
}
}
}
boolean topFirst = false;
for (int k = 0; k < bm.getHeight(); k++) {
for (int i = 0; i < bm.getWidth(); i++) {
int color = bm.getPixel(i, k);
if (color != 0) {
if (!topFirst) {
topFirst = true;
top = k;
}
bottom = k;
}
}
}
int centerX = (right - left) / 2 + left;
int centerY = (bottom - top) / 2 + top;
Log.e("ksksks",centerX+" "+centerY+" "+right +" "+ left+" "+bottom +" "+ top);
double suma = 0;
int x = 0,y = 0;
for (int i = 0; i < bm.getWidth(); i++) {
if (bm.getPixel(i, top) != 0) {
double a = Math.sqrt((centerX - i)*(centerX - i)+(centerY-top)*(centerY-top));
if(a>suma){
suma = a;
x = i;
y = top;
}
}
if (bm.getPixel(i, bottom) != 0) {
double a = Math.sqrt((centerX - i)*(centerX - i)+(centerY-bottom)*(centerY-bottom));
if(a>suma){
suma = a;
x = i;
y = bottom;
}
}
}
for (int i = 0; i < bm.getHeight(); i++) {
if (bm.getPixel(left, i) != 0) {
double a = Math.sqrt((centerX - left)*(centerX - left)+(centerY-i)*(centerY-i));
if(a>suma){
suma = a;
x = left;
y = i;
}
}
if (bm.getPixel(right, i) != 0) {
double a = Math.sqrt((centerX - right)*(centerX - right)+(centerY-i)*(centerY-i));
if(a>suma){
suma = a;
x = right;
y = i;
}
}
}
Paint paint = new Paint();
paint.setColor(Color.YELLOW);
paint.setStrokeWidth(5);
Canvas canvas = new Canvas(bm);
canvas.drawLine(centerX,centerY,x,y,paint);
iviv.setImageBitmap(bm);
} else {
Log.e("ksksk", " 1111111");
}
}
既然都做完了。。最终也得展示一下效果视频咯:
水表识别