Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Identifying and selecting floor in a room

I am new to OpenCV and have been reading a lot to help me achieve this. I need to be able to identify the floor of a room. I have looked at a lot of other questions and answers but none of them have been able to help me out.

One of the suggestions said:

  1. Load your image

  2. Sharpen your image by applying a Laplacian convolution filter

  3. Convert your image to grayscale

  4. Threshold the image to filter out noisy components

  5. Morph, dilate then apply watershed to separate planes

  6. Then find contours in the filtered image

Here is the code that I have tried so far:

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.photo.Photo;

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

public class IdentifyRoom {
  public static void main(String []args) {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

    Random rng = new Random(12345);

    Mat srcGray = new Mat();
    String filename = args.length > 0 ? args[0] : "../../room.jpg";
    Mat source = Imgcodecs.imread(filename);
    if (source.empty()) {
      System.err.println("Cannot read image: " + filename);
      System.exit(0);
    }

    Mat destination = new Mat(source.rows(), source.cols(), source.type());
    int kernelSize = 9;
    Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F) {
      {
        put(0,0,0);
        put(0,1,-1);
        put(0,2,0);

        put(1,0-1);
        put(1,1,4);
        put(1,2,-1);

        put(2,0,0);
        put(2,1,-1);
        put(2,2,0);
      }
    };

    Imgproc.filter2D(source, destination, -1, kernel);

    /// Convert image to gray and blur it
    Imgproc.cvtColor(source, srcGray, Imgproc.COLOR_BGR2GRAY);
    Imgproc.blur(srcGray, srcGray, new Size(3, 3));

    // histogram equalization
    Imgproc.equalizeHist(srcGray, srcGray);

    // denoise
    Imgproc.threshold(srcGray, srcGray, 25, 255, Imgproc.THRESH_BINARY_INV);

    Mat morphingMatrix = Mat.ones(1,1, CvType.CV_8UC1);
    Imgproc.morphologyEx(srcGray, srcGray, Imgproc.MORPH_OPEN, morphingMatrix);

    // Image denoising
    Photo.fastNlMeansDenoising(srcGray, srcGray);

    // dilate
    int dilation_size = 5;
    Mat element1 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new  Size(dilation_size, dilation_size));
    Imgproc.dilate(srcGray, srcGray, element1);

    // watershed // does not work
    /* Mat marker_tempo = new Mat();
    Mat rgba = new Mat();
    Mat threeChannel = new Mat();
    Imgproc.cvtColor(rgba, threeChannel, Imgproc.COLOR_RGB2GRAY);
    Imgproc.threshold(threeChannel, threeChannel, 100, 255, Imgproc.THRESH_OTSU);

    Mat markers = new Mat(rgba.size(),CvType.CV_8U, new Scalar(0));

    markers.convertTo(marker_tempo, CvType.CV_32S);
    Imgproc.watershed(rgba, marker_tempo);
    marker_tempo.convertTo(markers,CvType.CV_8U); */


    /// Find contours
    List<MatOfPoint> contours = new ArrayList<>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(srcGray, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

    Mat drawing = Mat.zeros(srcGray.size(), CvType.CV_8UC3);
    // Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
    for (int i = 0; i < contours.size(); i++) {
      Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
      // Imgproc.drawContours(drawing, contours, i, color, Imgproc.LINE_8);
      Imgproc.drawContours(drawing, contours, i, color, 2, Imgproc.LINE_8, hierarchy, 0, new Point());
    }

    Imgcodecs.imwrite("../../output1.jpg", drawing);
  }
}

Source

The source image

Output

The output

Identifying and selecting floor in a room

I am new to OpenCV and have been reading a lot to help me achieve this. I need to be able to identify the floor of a room. I have looked at a lot of other questions and answers but none of them have been able to help me out.

One of the suggestions said:

  1. Load your image

  2. Sharpen your image by applying a Laplacian convolution filter

  3. Convert your image to grayscale

  4. Threshold the image to filter out noisy components

  5. Morph, dilate then apply watershed to separate planes

  6. Then find contours in the filtered image

Here is the code that I have tried so far:

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.photo.Photo;

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

public class IdentifyRoom {
  public static void main(String []args) {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

    Random rng = new Random(12345);

    Mat srcGray = new Mat();
    String filename = args.length > 0 ? args[0] : "../../room.jpg";
    Mat source = Imgcodecs.imread(filename);
    if (source.empty()) {
      System.err.println("Cannot read image: " + filename);
      System.exit(0);
    }

    Mat destination = new Mat(source.rows(), source.cols(), source.type());
    int kernelSize = 9;
    Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F) {
      {
        put(0,0,0);
        put(0,1,-1);
        put(0,2,0);

        put(1,0-1);
        put(1,1,4);
        put(1,2,-1);

        put(2,0,0);
        put(2,1,-1);
        put(2,2,0);
      }
    };

    Imgproc.filter2D(source, destination, -1, kernel);

    /// Convert image to gray and blur it
    Imgproc.cvtColor(source, srcGray, Imgproc.COLOR_BGR2GRAY);
    Imgproc.blur(srcGray, srcGray, new Size(3, 3));

    // histogram equalization
    Imgproc.equalizeHist(srcGray, srcGray);

    // denoise
    Imgproc.threshold(srcGray, srcGray, 25, 255, Imgproc.THRESH_BINARY_INV);

    Mat morphingMatrix = Mat.ones(1,1, CvType.CV_8UC1);
    Imgproc.morphologyEx(srcGray, srcGray, Imgproc.MORPH_OPEN, morphingMatrix);

    // Image denoising
    Photo.fastNlMeansDenoising(srcGray, srcGray);

    // dilate
    int dilation_size = 5;
    Mat element1 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new  Size(dilation_size, dilation_size));
    Imgproc.dilate(srcGray, srcGray, element1);

    // watershed // does not work
    /* Mat marker_tempo = new Mat();
    Mat rgba = new Mat();
    Mat threeChannel = new Mat();
    Imgproc.cvtColor(rgba, threeChannel, Imgproc.COLOR_RGB2GRAY);
    Imgproc.threshold(threeChannel, threeChannel, 100, 255, Imgproc.THRESH_OTSU);

    Mat markers = new Mat(rgba.size(),CvType.CV_8U, new Scalar(0));

    markers.convertTo(marker_tempo, CvType.CV_32S);
    Imgproc.watershed(rgba, marker_tempo);
    marker_tempo.convertTo(markers,CvType.CV_8U); */


    /// Find contours
    List<MatOfPoint> contours = new ArrayList<>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(srcGray, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

    Mat drawing = Mat.zeros(srcGray.size(), CvType.CV_8UC3);
    // Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
    for (int i = 0; i < contours.size(); i++) {
      Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
      // Imgproc.drawContours(drawing, contours, i, color, Imgproc.LINE_8);
      Imgproc.drawContours(drawing, contours, i, color, 2, Imgproc.LINE_8, hierarchy, 0, new Point());
    }

    Imgcodecs.imwrite("../../output1.jpg", drawing);
  }
}

Source

The source image

Output

The output