OpenCV图像为黑白形状

Og *_*dik 4 c++ opencv image image-processing shapes

我希望手形图像是手的黑白形状.这是输入和所需输出的示例:手黑白http://imageshack.us/a/img853/4017/handtobw.jpg

使用阈值不会产生所需的输出,因为手内的一些颜色与背景颜色相同.我怎样才能获得所需的输出?

1''*_*1'' 5

自适应阈值,找到轮廓,填充

基本上,自适应阈值会将您的图像转换为黑白图像,但会根据每个像素周围的局部条件获取阈值级别 - 这样,您应该避免使用普通阈值时遇到的问题.事实上,我不确定为什么有人会想要使用正常的阈值.

如果这不起作用,另一种方法是找到图像中最大的轮廓,将其绘制到单独的矩阵上,然后用黑色填充其中的所有内容.(Floodfill就像MSPaint中的桶工具 - 它从特定像素开始,并填充连接到该像素的所有内容,与您选择的另一种颜色相同.)

对于各种照明条件,最强大的方法可能是按照顶部的顺序完成所有这些操作.但是你可能只能通过门槛或countours/floodfill逃脱.

顺便说一句,也许最棘手的部分实际上是找到轮廓,因为findContours返回一个arraylist/vector/MatOfPoints的任何(取决于我认为的平台).MatOfPoint是Mat的子类,但你不能直接绘制它 - 你需要使用drawContours.以下是我所知道的OpenCV4Android的一些代码:

    private Mat drawLargestContour(Mat input) {
    /** Allocates and returns a black matrix with the 
     * largest contour of the input matrix drawn in white. */

    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();        
    Imgproc.findContours(input, contours, new Mat() /* hierarchy */, 
            Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); 
    double maxArea = 0;
    int index = -1;
    for (MatOfPoint contour : contours) { // iterate over every contour in the list
        double area = Imgproc.contourArea(contour);
        if (area > maxArea) {
            maxArea = area;
            index = contours.indexOf(contour);
        }
    }

    if (index == -1) {
        Log.e(TAG, "Fatal error: no contours in the image!");
    }

    Mat border = new Mat(input.rows(), input.cols(), CvType.CV_8UC1); // initialized to 0 (black) by default because it's Java :)
    Imgproc.drawContours(border, contours, index, new Scalar(255)); // 255 = draw contours in white
    return border;
}
Run Code Online (Sandbox Code Playgroud)