2

我正在开发一个程序来检测从高分辨率相机拍摄的图像中的皱纹。目前,该项目处于启动阶段。到目前为止,我已经执行了以下步骤:

  1. 转换为灰度并对比图像。
  2. 使用高斯模糊去除噪点。
  3. 应用自适应阈值来检测皱纹。
  4. 使用膨胀来增强检测到的皱纹的大小,并尽可能多地连接单个皱纹的不同元素。
  5. 通过找到轮廓并去除面积较小的轮廓来去除噪音。

这是相同的代码:

package Wrinkle.Detection;

import java.util.ArrayList;
import java.util.List;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

public class DetectWrinkle {

    private Mat sourceImage;
    private Mat destinationImage;
    private Mat thresh;

    public void detectUsingThresh(String filename) {
        sourceImage =  Highgui.imread(filename, Highgui.CV_LOAD_IMAGE_GRAYSCALE);

        //Contrast
        Mat contrast = new Mat(sourceImage.rows(), sourceImage.cols(), sourceImage.type());
        Imgproc.equalizeHist(sourceImage, contrast);
        Highgui.imwrite("wrinkle_contrast.jpg", contrast);

        //Remove Noise
        destinationImage = new Mat(contrast.rows(), contrast.cols(), contrast.type());
        Imgproc.GaussianBlur(contrast, destinationImage,new Size(31,31), 0);
        Highgui.imwrite("wrinkle_Blur.jpg", destinationImage);

        //Apply Adaptive threshold
        thresh = new Mat();
        Imgproc.adaptiveThreshold(destinationImage, thresh, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY_INV, 99, 10);
        Highgui.imwrite("wrinkle_threshold.jpg", thresh);

        // dilation 
        Mat element1 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new  Size(2*3+1, 2*6+1));
        Imgproc.dilate(thresh, thresh, element1);
        Highgui.imwrite("wrinkle_thresh_dilation.jpg", thresh);

        //Find contours
        List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); 
        Mat image32S = new Mat();
        Mat threshClone = thresh.clone();
        threshClone.convertTo(image32S, CvType.CV_32SC1);
        Imgproc.findContours(image32S, contours, new Mat(), Imgproc.RETR_FLOODFILL,Imgproc.CHAIN_APPROX_SIMPLE);

        //Find contours with smaller area and color them to black (removing furhter noise)
        Imgproc.cvtColor(thresh, thresh, Imgproc.COLOR_GRAY2BGR); 
        for (int c=0; c<contours.size(); c++) {
            double value = Imgproc.contourArea(contours.get(c));
            if(value<500){
                Imgproc.drawContours(thresh, contours, c, new Scalar(0, 0, 0), -1); 
            }
        }
        Highgui.imwrite("wrinkle_contour_fill.jpg", thresh);

    }

    public static void main(String[] args) {
        DetectWrinkle dw = new DetectWrinkle();
        System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
        String imagefile = "wrinkle_guo (1).bmp";
        dw.detectUsingThresh(imagefile);
    }
}

问题: 正如您从下图中显示的结果中看到的那样,皮肤上的单个皱纹正在分解成单独的小元素。在这里,我试图通过扩张来连接这些元素以显示完整的皱纹。完成后,我首先检测轮廓,计算轮廓的面积,然后去除面积小于特定值的轮廓,从而消除噪声。

然而,这并没有给我一个正确的结果,所以我觉得可能有一些更好的方法来连接破碎的皱纹元素。请帮我解决这个问题。

如果这个问题有任何问题,请原谅我,因为我真的需要一个解决方案,而且我是这里的新手。

以下是图片:

输入图像 得到轮廓并通过寻找轮廓区域去除噪声后

4

0 回答 0