I'm doing an Android mobile application using OpenCV library that processes an image that we capture with our smartphone thru the app, it will process the image to detect skin color values (that has upper threshold and lower threshold) and use edge detection to draw white lines around that color range. So far can only detect the skin tone but I have no clue how to extract the skin color values in RGB/HSV numbers like (255,255,255) or the float HSV values. These values are going to be compared with liquid foundation shades to obtain which shades are the nearest to the skin in the image. I am aware of the lighting variables and so on but still want to get the values of the color. Any ideas on how i go around this? I have imported the library and they worked. Sample of the OpenCV code is as below and the sample of output:
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.imgcodecs.*;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == IMAGE_REQUEST && resultCode == RESULT_OK) {
Bitmap myBitmap = BitmapFactory.decodeFile(currentImagePath);
imageView.setImageBitmap(myBitmap);
//until here works and tested
Utils.bitmapToMat(myBitmap, mRgbMat);
Imgproc.cvtColor(mRgbMat, mHsvMat, Imgproc.COLOR_RGB2HSV, channelCount);
Scalar lowerThreshold = new Scalar(0, 48, 80); // lower hsv values
Scalar upperThreshold = new Scalar(20, 255, 255); // higher hsv values
Core.inRange(mHsvMat, lowerThreshold, upperThreshold, mMaskMat);
Imgproc.dilate(mMaskMat, mDilatedMat, new Mat());
//Scalar used = new Scalar(Core.inRange(mHsvMat, lowerThreshold, upperThreshold, mMaskMat));
Imgproc.findContours(mMaskMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// Find max contour area
double maxArea = 0;
Iterator<MatOfPoint> each = contours.iterator();
while (each.hasNext()) {
MatOfPoint wrapper = each.next();
double area = Imgproc.contourArea(wrapper);
if (area > maxArea)
maxArea = area;
}
// Filter contours by area and resize to fit the original image size
mMaxContours.clear();
each = contours.iterator();
while (each.hasNext()) {
MatOfPoint contour = each.next();
if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) {
mMaxContours.add(contour);
}
}
Imgproc.drawContours(mRgbMat, mMaxContours,0, colorGreen, iLineThickness);
Log.d(TAG + " contours" , contours.size() + " used colour: " + mHsvMat );
// convert to bitmap:
Bitmap bm = Bitmap.createBitmap(mRgbMat.cols(), mRgbMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mRgbMat, bm);
// find the imageview and draw it!
imageView2.setImageBitmap(bm);
}
The Skin RGB Value in the app shown below is from android.pallette by getRGB from getDominantSwatch. The value is not correct. I hope any experts out there can give opinions on this as I am just a newbie in opencv but i'm eager to learn.