Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

detect HSV color for skin color and extract the color in that region

The following is the code that I run to find the face region

private Mat mRgbMat;
private Mat mHsvMat;
private Mat mMaskMat;
private int channelCount = 3;
private Mat mDilatedMat;
private List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

private Mat hierarchy;
private int iLineThickness = 5;
private org.opencv.core.Scalar colorGreen = new Scalar(0, 255, 0);
private static double mMinContourArea = 0.3;
private List<MatOfPoint> mMaxContours = new ArrayList<MatOfPoint>();

private void detectRegion() {

    //get the image from gallery and change it into bitmap
    Bitmap bmpTemp = originalImg.copy(Bitmap.Config.ARGB_8888, true);
    Utils.bitmapToMat(bmpTemp, mRgbMat);
    Imgproc.cvtColor(mRgbMat, mHsvMat, Imgproc.COLOR_RGB2HSV, channelCount);

    Scalar lowerThreshold = new Scalar(0, 0.23 * 255, 50); // Blue color – lower hsv values
    Scalar upperThreshold = new Scalar(50, 0.68 * 255, 255); // Blue color – higher hsv values
    Core.inRange(mHsvMat, lowerThreshold, upperThreshold, mMaskMat);
    Imgproc.dilate(mMaskMat, mDilatedMat, new Mat());

    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() + "" );
    Log.d(TAG + " contours" ,  mMaxContours.size() + "" );
    Log.d(TAG + " contours row col" ,  mMaxContours.get(0).toList().toString());
    Log.d(TAG + " contours " , mMaxContours.get(0).toString());
    counter++;

    // 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!
    imageView.setImageBitmap(bm);
}

Result of the above code:

please add https:// because I cannot post link. Thank you s11.postimg.org/myaf9fb4z/photo_2017_02_16_14_43_34.jpg

Although I can get a good result using the above function, I may not get the result that I want if there are some extra elements that contains a close value of the color like the following image.

please add https:// because I cannot post link. Thank you s27.postimg.org/gy04nnwzn/photo_2017_02_16_14_49_57.jpg

How do I change my code to fit this situation? Also I need to change the HSV value in this region. How can I get the HSV value in that region? Please give me some helps. Thank you very much.

click to hide/show revision 2
retagged

updated 2017-02-16 01:05:06 -0600

berak gravatar image

detect HSV color for skin color and extract the color in that region

The following is the code that I run to find the face region

private Mat mRgbMat;
private Mat mHsvMat;
private Mat mMaskMat;
private int channelCount = 3;
private Mat mDilatedMat;
private List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

private Mat hierarchy;
private int iLineThickness = 5;
private org.opencv.core.Scalar colorGreen = new Scalar(0, 255, 0);
private static double mMinContourArea = 0.3;
private List<MatOfPoint> mMaxContours = new ArrayList<MatOfPoint>();

private void detectRegion() {

    //get the image from gallery and change it into bitmap
    Bitmap bmpTemp = originalImg.copy(Bitmap.Config.ARGB_8888, true);
    Utils.bitmapToMat(bmpTemp, mRgbMat);
    Imgproc.cvtColor(mRgbMat, mHsvMat, Imgproc.COLOR_RGB2HSV, channelCount);

    Scalar lowerThreshold = new Scalar(0, 0.23 * 255, 50); // Blue color – lower hsv values
    Scalar upperThreshold = new Scalar(50, 0.68 * 255, 255); // Blue color – higher hsv values
    Core.inRange(mHsvMat, lowerThreshold, upperThreshold, mMaskMat);
    Imgproc.dilate(mMaskMat, mDilatedMat, new Mat());

    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() + "" );
    Log.d(TAG + " contours" ,  mMaxContours.size() + "" );
    Log.d(TAG + " contours row col" ,  mMaxContours.get(0).toList().toString());
    Log.d(TAG + " contours " , mMaxContours.get(0).toString());
    counter++;

    // 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!
    imageView.setImageBitmap(bm);
}

Result of the above code:

please add https:// because I cannot post link. Thank you s11.postimg.org/myaf9fb4z/photo_2017_02_16_14_43_34.jpg

Although I can get a good result using the above function, I may not get the result that I want if there are some extra elements that contains a close value of the color like the following image.

please add https:// because I cannot post link. Thank you s27.postimg.org/gy04nnwzn/photo_2017_02_16_14_49_57.jpg

How do I change my code to fit this situation? Also I need to change the HSV value in this region. How can I get the HSV value in that region? Please give me some helps. Thank you very much.

detect HSV color for skin color and extract the color in that region

The following is the code that I run to find the face region

private Mat mRgbMat;
private Mat mHsvMat;
private Mat mMaskMat;
private int channelCount = 3;
private Mat mDilatedMat;
private List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

private Mat hierarchy;
private int iLineThickness = 5;
private org.opencv.core.Scalar Scalar colorGreen = new Scalar(0, 255, 0);
private static double mMinContourArea = 0.3;
private List<MatOfPoint> mMaxContours = new ArrayList<MatOfPoint>();

private void detectRegion() {

    //get the image from gallery and change it into bitmap
    Bitmap bmpTemp = originalImg.copy(Bitmap.Config.ARGB_8888, true);
    Utils.bitmapToMat(bmpTemp, mRgbMat);
    Imgproc.cvtColor(mRgbMat, mHsvMat, Imgproc.COLOR_RGB2HSV, channelCount);

    Scalar lowerThreshold = new Scalar(0, 0.23 * 255, 50); // Blue color – lower hsv values
    Scalar upperThreshold = new Scalar(50, 0.68 * 255, 255); // Blue color – higher hsv values
    Core.inRange(mHsvMat, lowerThreshold, upperThreshold, mMaskMat);
    Imgproc.dilate(mMaskMat, mDilatedMat, new Mat());

    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() + "" );
    Log.d(TAG + " contours" ,  mMaxContours.size() + "" );
    Log.d(TAG + " contours row col" ,  mMaxContours.get(0).toList().toString());
    Log.d(TAG + " contours " , mMaxContours.get(0).toString());
    counter++;

    // 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!
    imageView.setImageBitmap(bm);
}

Result of the above code:

please add https:// because I cannot post link. Thank you s11.postimg.org/myaf9fb4z/photo_2017_02_16_14_43_34.jpg

Although I can get a good result using the above function, I may not get the result that I want if there are some extra elements that contains a close value of the color like the following image.

please add https:// because I cannot post link. Thank you s27.postimg.org/gy04nnwzn/photo_2017_02_16_14_49_57.jpg

How do I change my code to fit this situation? Also I need to change the HSV value in this region. How can I get the HSV value in that region? Please give me some helps. Thank you very much.

detect HSV color for skin color and extract the color in that region

The following is the code that I run to find the face region

private Mat mRgbMat;
private Mat mHsvMat;
private Mat mMaskMat;
private int channelCount = 3;
private Mat mDilatedMat;
private List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

private Mat hierarchy;
private int iLineThickness = 5;
private Scalar colorGreen = new Scalar(0, 255, 0);
private static double mMinContourArea = 0.3;
private List<MatOfPoint> mMaxContours = new ArrayList<MatOfPoint>();

private void detectRegion() {

    //get the image from gallery and change it into bitmap
    Bitmap bmpTemp = originalImg.copy(Bitmap.Config.ARGB_8888, true);
    Utils.bitmapToMat(bmpTemp, mRgbMat);
    Imgproc.cvtColor(mRgbMat, mHsvMat, Imgproc.COLOR_RGB2HSV, channelCount);

    Scalar lowerThreshold = new Scalar(0, 0.23 * 255, 50); // Blue color – lower hsv values
    Scalar upperThreshold = new Scalar(50, 0.68 * 255, 255); // Blue color – higher hsv values
    Core.inRange(mHsvMat, lowerThreshold, upperThreshold, mMaskMat);
    Imgproc.dilate(mMaskMat, mDilatedMat, new Mat());

    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() + "" );

    // 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!
    imageView.setImageBitmap(bm);
}

Result of the above code:

please add https:// because I cannot post link. Thank you s11.postimg.org/myaf9fb4z/photo_2017_02_16_14_43_34.jpg

Although I can get a good result using the above function, I may not get the result that I want if there are some extra elements that contains a close value of the color like the following image.

please add https:// because I cannot post link. Thank you s27.postimg.org/gy04nnwzn/photo_2017_02_16_14_49_57.jpg

How do I change my code to fit this situation? Also I need to change the HSV value in this region. How can I get the HSV value in that region? Please give me some helps. Thank you very much.