Соедините ломаные линии обнаруженных морщин на изображении, используя Java opencv
Я работаю над программой для обнаружения морщин на изображении, снятом камерой высокого разрешения. В настоящее время проект находится в начальной стадии. До сих пор я выполнил следующие шаги:
- Преобразовать в оттенки серого и контрастировать изображение.
- Удалите шум, используя Gaussian Blur.
- Применить адаптивный порог для обнаружения морщин.
- Используйте расширение, чтобы увеличить размер обнаруженной морщины и максимально объединить разрозненные элементы одной морщины.
- Удалите шум, найдя контуры и удалив области с меньшими участками.
Вот код того же самого:
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);
}
}
Вопрос: Как видно из результатов, показанных ниже на изображениях, одна морщина на коже разбивается на отдельные мелкие элементы. Здесь я пытаюсь соединить эти элементы, чтобы показать полную морщинку, используя дилат. Как только это будет сделано, я удаляю шум, сначала обнаруживая контуры, вычисляя площадь контуров, а затем удаляя контуры с площадью меньше определенного значения.
Тем не менее, это не дает мне должного результата, поэтому я чувствую, что мог бы быть какой-то лучший способ соединения разорванных элементов морщины. Пожалуйста, помогите мне решить это.
И, пожалуйста, простите меня, если что-то не так с вопросом, потому что мне действительно нужно решение, и я новичок здесь.
Ниже приведены изображения:
Входное изображение После получения контуров и устранения шума путем нахождения области контура