2017-11-28 4 views
2

Update 1Haut und Bild erfassen

Ich habe eine Idee, was inRange Funktion tut. Aber ich möchte keine Maske anwenden und das neue Bild mit Hautfarbe zeigen. Was ich tun möchte, ist zu wissen, ob das Bild Hautfarbe enthält und einen größeren Bereich abdeckt.

Was will ich

ich ein Bild aufnehmen möchte, tun, wenn Finger in einer Grenze erkannt wird. Seine Dimensionen sind bekannt.

Struggling Punkte

  1. Manipulieren von Bilddaten in nativen Code.
  2. in Live-Kamera-Erkennung Haut, so, wenn dieser bestimmte Bereich fokussiert ist und die Haut erkannt wird, schnappen sollte

Was ich

I Layer bin mit JNI getan genommen werden, um die Operation durchzuführen . Ich bin in der Lage, Mat von Bilddaten mit this tutorial zu bekommen, aber weiß nicht, wie man poutPixels manipuliert. Das Format ist NV21 und ich bin nicht sicher, wie man Operationen darauf durchführt.

Ich muss Bild zuschneiden und dann feststellen, ob Haut in dem Bild vorhanden ist. Ich habe das Bild erfolgreich auf die gewünschte Größe zugeschnitten, aber ich habe keine Ahnung, wie ich mich vorwärts bewegen kann, um die Haut zu erkennen. Ich möchte, dass diese Methode true oder false zurückgibt. Hier

ist der Code:

jbyte * pNV21FrameData = env->GetByteArrayElements(NV21FrameData, 0); 
jint * poutPixels = env->GetIntArrayElements(outPixels, 0); 

Mat mNV(height, width, CV_8UC3, (unsigned char*)pNV21FrameData); 
Mat finalImage(height, width, CV_8UC3, (unsigned char*) poutPixels); 

jfloat wScale = (float) width/screenWidth; 
jfloat hScale = (float) height/screenHeight; 

float temp = rectX * wScale; 
int x = (int) temp; 
temp = rectY * hScale; 
int y = (int) temp; 

int cW = (int) (width * wScale); 
int cH = (int) (height * hScale); 

cH = cH/2; 


Rect regionToCrop(x, y, cW, cH); 
mNV = mNV(regionToCrop); 
finalImage = finalImage(regionToCrop); 

//detect skin and return true or false 

Ich habe über inRange Funktion gelesen, aber ich weiß nicht, wie zu überprüfen, ob die Haut dort ist oder nicht.

Fragen

  1. Bin ich auf dem richtigen Weg weiter zu gehen?
  2. Das Bildformat, das ich bekomme, ist NV21. Ist es ein 8UC1 oder kann es 8UC3 auch sein?
  3. Wie gehe ich von hier aus vor, um die Haut zu erkennen?

Jede Hilfe wird geschätzt.

Antwort

-1

Ich habe mein Problem gelöst, indem ich den Hautfarbenbereich extrahiert und alle Pixel gleich zero gemacht habe. Unten sind die Schritte.

  1. Konvertieren Sie das Bild auf HSV

Erste convert Bild HSV.

Mat mHsv = new Mat(rows, cols, CvType.CV_8UC3); 
Imgproc.cvtColor(mRgba, mHsv, Imgproc.COLOR_RGB2HSV); 
  1. Get Bereich der Hautfarbe

Hautfarbe Bereich variieren, aber dieses arbeitet für mich.

Mat output = new Mat(); 
Core.inRange(mHsv, new Scalar(0, 0.18*255, 0), new Scalar(25, 0.68*255, 255), output); 
  1. Extract Skin Bereich Kanal

nun diesen Kanal extrahieren, während Haut Pixel gleich zero

Mat mExtracted = new Mat(); 
Core.extractChannel(output, mExtracted, 0); 

Jetzt machen Sie haben mExtracted Matrix , in denen hautfarbene Pixel sind 0 und Reste sind 255 (oder Hautfarbe, ich bin mir nicht sicher).

  1. Get Anzahl der Nullen

Seit 0 jetzt tatsächlich Hautfarbenbereich ist, was Sie tun können, ist eine Schwelle zu definieren, die Ihren Bedürfnissen entspricht. Nach meinem Bedürfnis möchte ich, dass die Haut mehr als die Hälfte der Fläche bedeckt, also habe ich meine Logik dementsprechend gemacht.

int n = Core.countNonZero(mExtracted); 
int check = (mExtracted.rows() * mExtracted.cols())/2; 

if(n >= check && isFocused) { 
    //Take picture 
} 
+0

Es ist wirklich nett Geste nach dem Kommentar zu kommentieren, damit andere auch von deiner Weisheit lernen können. –