温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android中怎么基于肤色实现皮肤检测

发布时间:2021-06-29 14:13:27 来源:亿速云 阅读:160 作者:Leah 栏目:移动开发

这期内容当中小编将会给大家带来有关Android中怎么基于肤色实现皮肤检测,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

在android上实现基于肤色的皮肤检测的几个技术要点:

(1)android上使用相机预览,包括相机api的使用和surfaceview的应用。

(2)android上相机使用的色彩空间NV12.

(3)NV12是YCrCb的色彩空间,了解YCrCb色彩空间。YCrCb和YUV之间的转换。

yuv色彩模型来源于rgb模型,该模型的特点是将亮度和色度分离开,从而适合于图像处理领域。YCbCr模型来源于yuv模型.

(4)YCrCb色彩空间表示的人类肤色的特征。这个特征是133≤Cr≤173,77≤Cb≤127.实验表明Cr在[140,160]区间是符合黄种人的肤色。

YUV和RGB的转换:

★这里是不是不是yuv而是Y Cb Cr???★

Y = 0.299 R + 0.587 G + 0.114 B

U = -0.1687 R - 0.3313 G + 0.5 B + 128

V = 0.5 R - 0.4187 G - 0.0813 B + 128

R = Y + 1.402 (V-128)

G = Y - 0.34414 (U-128) - 0.71414 (V-128)

B = Y + 1.772 (U-128)

以前,一直没明白yuv和YcbCr之间的差异,想必有些朋友也会有同样的疑惑。

所以,我看完之后就记载下来了。

一、和rgb之间换算公式的差异

yuv<-->rgb

Y'= 0.299*R' + 0.587*G' + 0.114*B'

U'= -0.147*R' - 0.289*G' + 0.436*B' = 0.492*(B'- Y')

V'= 0.615*R' - 0.515*G' - 0.100*B' = 0.877*(R'- Y')

R' = Y' + 1.140*V'

G' = Y' - 0.394*U' - 0.581*V'

B' = Y' + 2.032*U'

yCbCr<-->rgb

Y&rsquo; = 0.257*R' + 0.504*G' + 0.098*B' + 16

Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128

Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128

R' = 1.164*(Y&rsquo;-16) + 1.596*(Cr'-128)

G' = 1.164*(Y&rsquo;-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)

B' = 1.164*(Y&rsquo;-16) + 2.017*(Cb'-128)

Note: 上面各个符号都带了一撇,表示该符号在原值基础上进行了gamma correction

源代码如下:

001 package com.example.hearrate; 002   003 import java.io.FileNotFoundException; 004 import java.io.FileOutputStream; 005 import java.io.IOException; 006 import java.util.List; 007   008 import android.graphics.Bitmap; 009 import android.graphics.BitmapFactory; 010 import android.graphics.Canvas; 011 import android.graphics.Color; 012 import android.graphics.Paint; 013 import android.graphics.PixelFormat; 014 import android.graphics.PorterDuffXfermode; 015 import android.graphics.Rect; 016 import android.hardware.Camera; 017 import android.hardware.Camera.CameraInfo; 018 import android.hardware.Camera.Size; 019 import android.os.AsyncTask; 020 import android.os.Build; 021 import android.os.Bundle; 022 import android.annotation.SuppressLint; 023 import android.app.Activity; 024 import android.content.res.Configuration; 025 import android.util.Log; 026 import android.view.Menu; 027 import android.view.SurfaceHolder; 028 import android.view.SurfaceView; 029 import android.graphics.PorterDuff; 030 import android.graphics.PorterDuff.Mode; 031 public class MainActivity extends Activity implements  SurfaceHolder.Callback ,Camera.PreviewCallback{ 032 SurfaceHolder mHolder; 033 SurfaceView mView; 034 SurfaceView mLayer; 035 SurfaceHolder mLayerHolder; 036 private Camera mCamera =null; 037 private boolean bIfPreview =false; 038 private int mPreviewHeight; 039 private int mPreviewWidth; 040 private Canvas canvas; 041 private Paint paint; 042 private int facex=0,facey=0; 043 private boolean bprocessing=false; 044 private int[] RGBData; 045 private byte[] mYUVData;   046 private boolean bfront=false; 047     @Override 048     protected void onCreate(Bundle savedInstanceState) { 049         super.onCreate(savedInstanceState); 050         setContentView(R.layout.activity_main); 051         mView=(SurfaceView)findViewById(R.id.layer0); 052         paint = new Paint(); 053         paint.setColor(Color.RED); 054         paint.setAntiAlias(true); 055   056         mPreviewWidth=320; 057         mPreviewHeight=400; 058         mHolder=mView.getHolder(); 059         mHolder.addCallback(this); 060         mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 061           062         mLayer=(SurfaceView)findViewById(R.id.layer1); 063         mLayer.setZOrderOnTop(true); 064         //mLayer.setEGLConfigChooser(8, 8, 8, 8, 16, 0); 065       066           067         mLayerHolder=mLayer.getHolder(); 068         mLayerHolder.setFormat(PixelFormat.TRANSPARENT); 069         mLayerHolder.addCallback(this); 070         mLayerHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 071     } 072 void drawlayer1() 073 { 074     canvas=mLayerHolder.lockCanvas(); 075     // canvas.drawRGB(0, 0, 0); 076     // canvas.save(); 077      Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); 078      //绘制 079     // canvas.drawBitmap(bmp, null, paint); 080      drawImage(canvas,bmp,facex,facex,72,72,0,0); 081      canvas.restore(); 082      bmp=null; 083      mLayerHolder.unlockCanvasAndPost(canvas); 084 } 085     @Override 086     public boolean onCreateOptionsMenu(Menu menu) { 087         // Inflate the menu; this adds items to the action bar if it is present. 088         getMenuInflater().inflate(R.menu.activity_main, menu); 089         return true; 090     } 091   092     @Override 093     public void surfaceChanged(SurfaceHolder arg0, int arg1, int width, int height) { 094         // TODO Auto-generated method stub 095         mPreviewWidth=width; 096         mPreviewHeight=height; 097         if(arg0.equals(mLayerHolder)) 098         { 099             //drawlayer1(); 100             return; 101         } 102           103         RGBData= new int[mPreviewHeight* mPreviewWidth]; 104         mYUVData= new byte[mPreviewHeight* mPreviewWidth+(mPreviewHeight/2)* (mPreviewWidth/2)+(mPreviewHeight/2)* (mPreviewWidth/2)]; 105             initCamera(); 106     } 107   108     @SuppressLint("NewApi") 109     @Override 110     public void surfaceCreated(SurfaceHolder arg0) { 111         // TODO Auto-generated method stub 112         // TODO Auto-generated method stub 113         if(arg0.equals(mLayerHolder)) 114             return; 115 if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.GINGERBREAD) 116 { 117 for(int i=0;i<Camera.getNumberOfCameras();i++) 118 { 119 CameraInfo info=new CameraInfo(); 120 Camera.getCameraInfo(i, info); 121 if(info.facing==CameraInfo.CAMERA_FACING_FRONT) 122 { 123     //mCamera = Camera.open(i); 124     //bfront=true; 125 } 126 } 127 } 128 if(mCamera==null) 129 { 130         mCamera = Camera.open();// 开启摄像头(2.3版本后支持多摄像头,需传入参数) 131         bfront=false; 132 } 133          try 134         { 135                136         mCamera.setPreviewDisplay(mHolder);//set the surface to be used for live preview 137           138         Log("成功打开"); 139         } catch (Exception ex) 140         { 141          if(null != mCamera) 142         { 143         mCamera.release(); 144         mCamera = null; 145         } 146          canvas=mHolder.lockCanvas(); 147          canvas.drawRGB(0, 0, 0); 148          canvas.save(); 149          Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.bg); 150          //绘制 151         // canvas.drawBitmap(bmp, null, paint); 152          drawImage(canvas,bmp,0,0,mPreviewWidth,mPreviewHeight,0,0); 153          canvas.restore(); 154          bmp=null; 155 mHolder.unlockCanvasAndPost(canvas); 156          Log("打开失败"+ex.getMessage()); 157         } 158     } 159 //  GameView.drawImage(canvas, mBitDestTop, miDTX, mBitQQ.getHeight(), mBitDestTop.getWidth(), mBitDestTop.getHeight()/2, 0, 0); 160   public static void drawImage(Canvas canvas, Bitmap blt, int x, int y, int w, int h, int bx, int by) 161   {                                                        //x,y表示绘画的起点, 162       Rect src = new Rect();// 图片 163       Rect dst = new Rect();// 屏幕位置及尺寸 164       //src 这个是表示绘画图片的大小 165       src.left = bx;   //0,0  166       src.top = by; 167       src.right = bx + w;// mBitDestTop.getWidth();,这个是桌面图的宽度, 168       src.bottom = by + h;//mBitDestTop.getHeight()/2;// 这个是桌面图的高度的一半 169       // 下面的 dst 是表示 绘画这个图片的位置 170       dst.left = x;    //miDTX,//这个是可以改变的,也就是绘图的起点X位置 171       dst.top = y;    //mBitQQ.getHeight();//这个是QQ图片的高度。 也就相当于 桌面图片绘画起点的Y坐标 172       dst.right = x + w;    //miDTX + mBitDestTop.getWidth();// 表示需绘画的图片的右上角 173       dst.bottom = y + h;    // mBitQQ.getHeight() + mBitDestTop.getHeight();//表示需绘画的图片的右下角 174       canvas.drawBitmap(blt, src, dst, null);//这个方法  第一个参数是图片原来的大小,第二个参数是 绘画该图片需显示多少。也就是说你想绘画该图片的某一些地方,而不是全部图片,第三个参数表示该图片绘画的位置 175         176       src = null; 177       dst = null; 178   } 179     @Override 180     public void surfaceDestroyed(SurfaceHolder arg0) { 181         // TODO Auto-generated method stub 182         if(arg0.equals(mLayerHolder)) 183             return; 184          if(null != mCamera) 185          { 186          mCamera.setPreviewCallback(null); //!!这个必须在前,不然退出出错 187          mCamera.stopPreview(); 188          bIfPreview = false; 189          mCamera.release(); 190          mCamera = null; 191          } 192     } 193   194   195     @Override 196     public void onPreviewFrame(byte[] data, Camera camera) { 197         // TODO Auto-generated method stub 198         Log("going into onPreviewFrame"+data.length); 199           200          int imageWidth = camera.getParameters().getPreviewSize().width  ; 201             int imageHeight =camera.getParameters().getPreviewSize().height ; 202           //  int RGBData[] = new int[imageWidth* imageHeight]; 203            if(!bprocessing) 204            { 205             System.arraycopy(data, 0, mYUVData, 0, data.length); 206               207             new ProcessTask().execute(mYUVData); 208            } 209           //  decodeYUV420SP(RGBData, mYUVData, imageWidth, imageHeight); 210   211          //   Bitmap bitmap = Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.ARGB_8888); 212          //   bitmap.setPixels(RGBData, 0, imageWidth, 0, 0, imageWidth, imageHeight); 213           //  FileOutputStream outStream = null; 214            // ByteArrayOutputStream baos = new ByteArrayOutputStream(); 215               216            // outStream = new FileOutputStream(String.format("/sdcard/%d.bmp", System.currentTimeMillis())); 217            // outStream.write(bitmap.); 218           //  outStream.close(); 219             /* 220             FileOutputStream out; 221             try { 222                 String path=String.format("/mnt/sdcard/%d.png", System.currentTimeMillis()); 223                 out = new FileOutputStream(path); 224                 bitmap.compress(Bitmap.CompressFormat.PNG, 90, out); 225                 out.close(); 226             } catch (FileNotFoundException e) { 227                 // TODO Auto-generated catch block 228                 e.printStackTrace(); 229             } catch (IOException e) { 230                 // TODO Auto-generated catch block 231                 e.printStackTrace(); 232             } 233     */ 234          //mYUV420sp = data; // 获取原生的YUV420SP数据 235     //int mInitPos= mPreviewWidth*mPreviewHeight; 236   237     //if(mYUV420sp.length<=mInitPos+1) 238     //  return; 239     //byte cr=0; 240     //int framesize=mInitPos; 241     //int uvp=0; 242     //int i,j,u=0,v=0,yp = 0; 243     //int uvp=framesize+(i>>1)*w+j; 244 //  canvas=mLayerHolder.lockCanvas(); 245     // canvas.drawRGB(0, 0, 0); 246 //  canvas.save(); 247     // Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); 248      //绘制 249     // canvas.drawBitmap(bmp, null, paint); 250     // drawImage(canvas,bmp,facex,facex,72,72,0,0); 251       252       253     // bmp=null; 254     //  int RGBData[] = new int[mPreviewHeight* mPreviewWidth]; 255    //   byte[] mYUVData = new byte[mYUV420sp.length];    256    //   System.arraycopy(mYUV420sp, 0, mYUVData, 0, mYUV420sp.length); 257 /* 258     for( i=0,yp = 0;i<mPreviewHeight;i++) 259     { 260         uvp=framesize+(i>>1)*mPreviewWidth; 261         for( j=0;j<mPreviewWidth;j++) 262         { 263             int y = (0xff & ((int) mYUVData[yp])) - 16; 264             if (y < 0) y = 0; 265               if((j&1)==0) 266                       { 267                 v = (0xff & mYUVData[uvp++]) - 128; 268                 u = (0xff & mYUVData[uvp++]) - 128; 269                      } 270              // if(133&le;Cr&le;173,77&le;Cb&le;127 271              if(v>133&&v<173) 272                 canvas.drawPoint(j, i, paint); 273                274              int y1192 = 1192 * y; 275   276             int r = (y1192 + 1634 * v); 277   278             int g = (y1192 - 833 * v - 400 * u); 279   280             int b = (y1192 + 2066 * u); 281   282             if (r < 0) r = 0; else if (r > 262143) r = 262143; 283   284         if (g < 0) g = 0; else if (g > 262143) g = 262143; 285   286             if (b < 0) b = 0; else if (b > 262143) b = 262143; 287         //  int rgb=0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); 288               289             //r=(rgb&0x00ff0000)>>4; 290         //  g=(rgb&0x0000ff00)>>2; 291         //  b=(rgb&0x000000ff); 292           //    if(r>200&&g>200&&b>200) 293            //     canvas.drawPoint(j, i, paint); 294             //rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); 295         } 296           297           298     } 299       300   301      canvas.restore(); 302      mLayerHolder.unlockCanvasAndPost(canvas); 303      */ 304 /* 305  * framesize=w*h; 306  * yp=0; 307  * for (int i=0;i<h;i++) 308  * { 309  *     uvp=framesize+(i>>1)*w; 310  *  for(int j=0;j<w;j++,yp++) 311  *  { 312  *  int y = (0xff & ((int) yuv420sp[yp])) - 16; 313  *     if(j&1==0) 314  *     { 315  *     v = (0xff & yuv420sp[uvp++]) - 128; 316   317 u = (0xff & yuv420sp[uvp++]) - 128; 318  *     } 319  *     320  *     321  *  } 322  * } 323  * 324  * 325  * */ 326     } 327     public void drawdetect() 328     { 329         canvas=mLayerHolder.lockCanvas(); 330         331         if(canvas==null) 332             return; 333         canvas.drawColor(Color.TRANSPARENT);  334         Paint p = new Paint();  335         //清屏   336          p.setXfermode(new PorterDuffXfermode(Mode.CLEAR));  337         canvas.drawPaint(p);  338         p.setXfermode(new PorterDuffXfermode(Mode.SRC));  339         canvas.save(); 340         canvas.drawBitmap(RGBData, 0, mPreviewWidth, 0, 0, mPreviewWidth, mPreviewHeight, true, p); 341           342          canvas.restore(); 343          mLayerHolder.unlockCanvasAndPost(canvas); 344     } 345     public void detectwhite(byte[] yuv420sp, int width, int height) 346     { 347         //检测所有白色 348         final int frameSize = width * height; 349   350         for (int j = 0, yp = 0; j < height; j++) { 351         int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; 352         for (int i = 0; i < width; i++, yp++) { 353             int y = (0xff & ((int) yuv420sp[yp])); 354             if (y < 0) y = 0; 355             if ((i & 1) == 0) { 356                 v = (0xff & yuv420sp[uvp++]);; 357                 u = (0xff & yuv420sp[uvp++]); 358             } 359             ///133&le;Cr&le;173,77&le;Cb&le;127 360 if(y>250) 361 { 362     RGBData[yp]=Color.RED; 363     // canvas.drawPoint(i, j, paint); 364     }else 365     { 366         RGBData[yp]=Color.TRANSPARENT; 367     } 368   369         } 370           371     } 372   373     } 374     public void detectface(byte[] yuv420sp, int width, int height) 375     { 376           377         final int frameSize = width * height; 378   379         for (int j = 0, yp = 0; j < height; j++) { 380         int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; 381         for (int i = 0; i < width; i++, yp++) { 382       383             if ((i & 1) == 0) { 384                 v = (0xff & yuv420sp[uvp++]);; 385                 u = (0xff & yuv420sp[uvp++]); 386             } 387             ///133&le;Cr&le;173,77&le;Cb&le;127 388 if((v)>133&&(v)<160&&(u>77)&&(u<127)) 389 { 390     RGBData[yp]=Color.RED; 391     // canvas.drawPoint(i, j, paint); 392     }else 393     { 394         RGBData[yp]=Color.TRANSPARENT; 395     } 396   397         } 398           399     } 400   401     } 402      public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { 403         final int frameSize = width * height; 404         canvas=mLayerHolder.lockCanvas(); 405         Paint paint1 = new Paint();  406         paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));  407         canvas.drawPaint(paint1); 408         canvas.save(); 409         for (int j = 0, yp = 0; j < height; j++) { 410         int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; 411         for (int i = 0; i < width; i++, yp++) { 412             int y = (0xff & ((int) yuv420sp[yp])) - 16; 413             if (y < 0) y = 0; 414             if ((i & 1) == 0) { 415                 v = (0xff & yuv420sp[uvp++]) - 128; 416                 u = (0xff & yuv420sp[uvp++]) - 128; 417             } 418             ///133&le;Cr&le;173,77&le;Cb&le;127 419 if((v)>133&&(v)<160&&(u>77)&&(u<127)) 420 { 421      canvas.drawPoint(i, j, paint); 422     } 423 /* 424  * 这个是yuv转RGB的处理  425  *   */ 426             int y1192 = 1192 * y; 427             int r = (y1192 + 1634 * v); 428             int g = (y1192 - 833 * v - 400 * u); 429             int b = (y1192 + 2066 * u); 430   431             if (r < 0) r = 0; else if (r > 262143) r = 262143; 432             if (g < 0) g = 0; else if (g > 262143) g = 262143; 433             if (b < 0) b = 0; else if (b > 262143) b = 262143; 434   435             rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); 436               437              r = (rgb[yp] >> 16)&0xff; 438                   g = (rgb[yp] >> 8) & 0xff; 439                    b = rgb[yp] & 0xff; 440                  //  if(r==255&&g==255&&b==255) 441                   // canvas.drawPoint(i, j, paint); 442   443       444         } 445           446     } 447      canvas.restore(); 448      mLayerHolder.unlockCanvasAndPost(canvas); 449 } 450   451   452     private void initCamera() 453     { 454         if (bIfPreview) 455         { 456             mCamera.stopPreview(); 457         } 458         if(null != mCamera) 459         { 460             try{ 461                 Camera.Parameters parameters = mCamera.getParameters(); 462                 // parameters.setFlashMode("off"); // 无闪光灯 463                  parameters.setPictureFormat(PixelFormat.JPEG); //Sets the image format for picture 设定相片格式为JPEG,默认为NV21 464                 parameters.setPreviewFormat(PixelFormat.YCbCr_420_SP); //Sets the image format for preview picture,默认为NV21 465                   466                  mCamera.setPreviewCallback(this); 467                  // 【调试】获取caera支持的PictrueSize,看看能否设置?? 468                 List pictureSizes = mCamera.getParameters().getSupportedPictureSizes(); 469                  List previewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 470                  List previewFormats = mCamera.getParameters().getSupportedPreviewFormats(); 471                 List previewFrameRates = mCamera.getParameters().getSupportedPreviewFrameRates(); 472                   473                   Size psize = null; 474                  for (int i = 0; i < pictureSizes.size(); i++) 475                  { 476                  psize = (Size) pictureSizes.get(i); 477                   478                  } 479                   for (int i = 0; i < previewSizes.size(); i++) 480                  { 481                  psize = (Size) previewSizes.get(i); 482                   483                   } 484                  Integer pf = null; 485                  for (int i = 0; i < previewFormats.size(); i++) 486                  { 487                 pf = (Integer) previewFormats.get(i); 488               489                  } 490                   491                 // 设置拍照和预览图片大小 492                  parameters.setPictureSize(640, 480); //指定拍照图片的大小 493                 parameters.setPreviewSize(mPreviewWidth, mPreviewHeight); // 指定preview的大小 494                  //这两个属性 如果这两个属性设置的和真实手机的不一样时,就会报错 495                 if(bfront) 496                 { 497                  parameters.set("orientation", "landscape"); // 498                  parameters.set("rotation", 0); // 镜头角度转90度(默认摄像头是横拍) 499                     mCamera.setDisplayOrientation(0); // 在2.2以上可以使用 500                 } 501                 // 横竖屏镜头自动调整 502             /*  if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) 503                  { 504                  parameters.set("orientation", "portrait"); // 505                  parameters.set("rotation", 90); // 镜头角度转90度(默认摄像头是横拍) 506                 mCamera.setDisplayOrientation(90); // 在2.2以上可以使用 507                  } else// 如果是横屏 508              { 509                  parameters.set("orientation", "landscape"); // 510                 mCamera.setDisplayOrientation(0); // 在2.2以上可以使用 511              } 512               */ 513                   //添加对视频流处理函数 514                 // 设定配置参数并开启预览 515                  mCamera.setParameters(parameters); // 将Camera.Parameters设定予Camera 516                  mCamera.startPreview(); // 打开预览画面 517                  bIfPreview = true; 518                  // 【调试】设置后的图片大小和预览大小以及帧率 519                  Camera.Size csize = mCamera.getParameters().getPreviewSize(); 520                  mPreviewHeight = csize.height; // 521                 mPreviewWidth = csize.width; 522                    523                  csize = mCamera.getParameters().getPictureSize(); 524                   525                   526             }catch(Exception e) 527             { 528                 Log(e.getMessage()); 529             } 530               531         } 532     } 533     void Log(String msg) 534     { 535         System.out.println("LOG:"+msg); 536     } 537     int[] g_v_table,g_u_table,y_table; 538     int[][] r_yv_table,b_yu_table; 539     int inited = 0; 540        541   542     void initTable() 543     { 544         g_v_table=new int[256]; 545         g_u_table=new int[256]; 546         y_table=new int[256]; 547         r_yv_table=new int[256][256]; 548         b_yu_table=new int[256][256]; 549         if (inited == 0) 550         { 551             inited = 1; 552             int m = 0,n=0; 553             for (; m < 256; m++) 554             { 555                 g_v_table[m] = 833 * (m - 128); 556                 g_u_table[m] = 400 * (m - 128); 557                 y_table[m] = 1192 * (m - 16); 558             } 559             int temp = 0; 560             for (m = 0; m < 256; m++) 561                 for (n = 0; n < 256; n++) 562                 { 563                     temp = 1192 * (m - 16) + 1634 * (n - 128); 564                     if (temp < 0) temp = 0; else if (temp > 262143) temp = 262143; 565                     r_yv_table[m][n] = temp; 566        567                     temp = 1192 * (m - 16) + 2066 * (n - 128); 568                     if (temp < 0) temp = 0; else if (temp > 262143) temp = 262143; 569                     b_yu_table[m][n] = temp; 570                 } 571         } 572     } 573     public class ProcessTask extends AsyncTask<byte[], Void, Void> 574     { 575   576         @Override 577         protected void onPostExecute(Void result) { 578             // TODO Auto-generated method stub 579             super.onPostExecute(result); 580             drawdetect(); 581             bprocessing=false; 582         } 583   584         @Override 585         protected void onPreExecute() { 586             // TODO Auto-generated method stub 587             super.onPreExecute(); 588             if(bprocessing) 589                 this.cancel(true); 590           591         } 592   593         @Override 594         protected Void doInBackground(byte[]... params) { 595             // TODO Auto-generated method stub 596             bprocessing=true; 597             byte[] data=    params[0];                                   //皮肤检测                 detectface(data,mPreviewWidth, mPreviewHeight);            //白色检测                 //detectwhite(data,mPreviewWidth, mPreviewHeight);           //  publishProgress(null);                 return null;             }                       }     }

以下是layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"         xmlns:tools="http://schemas.android.com/tools"         android:layout_width="match_parent"         android:layout_height="match_parent"         tools:context=".MainActivity" >                   <FrameLayout                     android:layout_width="match_parent"                     android:layout_height="match_parent" >                 <SurfaceView             android:id="@+id/layer0"             android:layout_width="match_parent"             android:layout_height="match_parent"             />       </FrameLayout>                  <FrameLayout               android:layout_width="match_parent"               android:layout_height="match_parent" >                 <SurfaceView             android:id="@+id/layer1"             android:layout_width="match_parent"             android:layout_height="match_parent"             />       </FrameLayout>            </RelativeLayout>

以下是manifest

  1. <?xml version="1.0" encoding="utf-8"?> 

  2.   <manifest xmlns:android="http://schemas.android.com/apk/res/android" 

  3.       package="com.example.hearrate" 

  4.       android:versionCode="1" 

  5.       android:versionName="1.0" >    

  6.       <uses-sdk 

  7.           android:minSdkVersion="8" 

  8.           android:targetSdkVersion="17" /> 

  9.   <uses-permission android:name="android.permission.CAMERA"/> 

  10.   <!-- 在SDCard中创建与删除文件权限 --> 

  11.    

  12. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>    

  13.   <!-- 往SDCard写入数据权限 -->    

  14.   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

  15.   <uses-feature android:name="android.hardware.camera"/> 

  16.   <uses-feature android:name="android.hardware.camera.autofocus"/>   

  17.   <application 

  18.           android:allowBackup="true" 

  19.           android:icon="@drawable/ic_launcher"

  20.          android:label="@string/app_name" 

  21.           android:theme="@style/AppTheme" > 

  22.           <activity 

  23.               android:name="com.example.hearrate.MainActivity" 

  24.               android:label="@string/app_name" 

  25.               android:theme="@android:style/Theme.NoTitleBar.Fullscreen" 

  26.               android:screenOrientation="landscape" 

  27.               > 

  28.               <intent-filter> 

  29.                   <action android:name="android.intent.action.MAIN" /> 

  30.                   <category android:name="android.intent.category.LAUNCHER" /> 

  31.               </intent-filter> 

  32.           </activity> 

  33.       </application> 

  34.   </manifest> 

上述就是小编为大家分享的Android中怎么基于肤色实现皮肤检测了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI