使用Java opencv

时间:2016-10-19 10:33:46

标签: java opencv image-processing adaptive-threshold

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

  1. 转换为灰度并对比图像。
  2. 使用高斯模糊消除噪音。
  3. 应用自适应阈值来检测皱纹。
  4. 使用扩张来增强检测到的皱纹的大小,并尽可能地加入单个皱纹的不同元素。
  5. 通过查找轮廓并移除较小区域的轮廓来消除噪音。
  6. 以下是相同的代码:

    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);
        }
    }
    

    问题: 从图像中显示的结果可以看出,皮肤上的单个皱纹被分解成单独的小元素。在这里,我试图通过使用扩张来连接这些元素以显示完整的皱纹。一旦完成,我通过首先检测轮廓,计算轮廓的面积,然后去除面积小于特定值的轮廓来消除噪音。

    然而,这并没有给我一个合适的结果,所以我觉得可以有更好的方法来加入破碎的皱纹元素。请帮我解决这个问题。

    请原谅我这个问题有什么问题,因为我真的需要一个解决方案而且我是新手。

    以下是图片:

    Input image After getting contours and removing noise by finding contour area

0 个答案:

没有答案