-1

I am trying to extract text from image(binarize) using opencv javacpp-presets (version 3.0.0-1.0) and using the code-snippit below. The snippit is a translate from this python version of the code.

The input image is from file and is loaded through imread but the code fails at findContours with the following error message:

OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file src\array.cpp, line 2494

Suggested solutions from here don't work for me. Any help greatly appreciated!

    // Load the image
    Mat image_orig = imread(inputFile);
    if ( image_orig.empty() ) { LOGGER.error("Empty image!");}

    this.image = new Mat();
    //Add a border to the image for processing sake
    copyMakeBorder(image_orig, this.image, 50, 50, 50, 50, BORDER_CONSTANT);

    //# Calculate the width and height of the image

    this.img_y = this.image.arrayHeight();
    this.img_x = this.image.arrayWidth();

    if (DEBUG)
        LOGGER.info("Image is " + this.img_x + "x" + this.img_x);

    //Split out each channel
    Mat red = new Mat();
    Mat green = new Mat();
    Mat blue = new Mat();

    MatVector v = new MatVector(blue, green, red);
    split(image, v);

    //Run canny edge detection on each channel
    Mat blue_edges = new Mat();
    Canny(blue, blue_edges, 200, 250);

    Mat green_edges = new Mat();
    Canny(green, green_edges, 200, 250);

    Mat red_edges = new Mat();
    Canny(red, red_edges, 200, 250);

    //Join edges back into image
    Mat edges = new Mat();
    MatVector vEdges = new MatVector(red_edges, green_edges, blue_edges);
    merge(vEdges, edges);

    //Find the contours
    Mat edgesCopy = new Mat();
    edges.copyTo(edgesCopy);

    Mat hierarchy = new Mat();
    MatVector contours = new MatVector();
    findContours(edgesCopy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);
Community
  • 1
  • 1
s.ijpma
  • 822
  • 1
  • 11
  • 22
  • 1
    Try converting your edgesCopy mat to greyscale before calling findContours. It requires the input to be an 8-bit image with a single channel. – user3510227 Aug 12 '15 at 07:30
  • Thanks for your response. i tried your suggestion with: `//convert to grayscale Mat gray = new Mat(); cvtColor(edges, gray, COLOR_BGR2GRAY); Mat blur = new Mat(); GaussianBlur(gray, blur, new Size(5,5), 0); Mat edgesCopy = new Mat(); adaptiveThreshold(blur, edgesCopy, 255,1,1,11,2);` but i am getting the same error message at `findContours` – s.ijpma Aug 12 '15 at 09:19
  • Are you sure the image is being read in correctly? Try checking the type after it's read in and just before you pass it to `findContours()` I think `Mat.type()` is the function call in the Java API. – user3510227 Aug 12 '15 at 09:33
  • `edgesCopy.type()` equals to 16 before converting to grayscale and after it equals to 0 – s.ijpma Aug 12 '15 at 09:48
  • i'm guessing splitting to multichannel doesn't work out? – s.ijpma Aug 12 '15 at 09:50
  • If I remember correctly a type of 0 is an 8-bit image, can you display it (try `imshow()`)? Things might be getting mixed up in your channel splitting, so I would try a simpler process: read the image in, convert to greyscale then find contours. I can write a quick example if you get stuck, it'd be in C++ though. – user3510227 Aug 12 '15 at 10:04

1 Answers1

1

Gosh, silly me. I should have used the input from the MatVector i.s.o. the empty Mat's for the Canny detection. Then using the grayscale as @user3510227 suggests i get the following working code:

    // Load the image
    Mat image_orig = imread(inputFile);
    if ( image_orig.empty() ) { LOGGER.error("Empty image!");}

    this.image = new Mat();
    //Add a border to the image for processing sake
    copyMakeBorder(image_orig, this.image, 50, 50, 50, 50, BORDER_CONSTANT);

    //# Calculate the width and height of the image

    this.img_y = this.image.arrayHeight();
    this.img_x = this.image.arrayWidth();

    if (DEBUG)
        LOGGER.info("Image is " + this.img_x + "x" + this.img_x);

    //Split out each channel
    Mat red = new Mat();
    Mat green = new Mat();
    Mat blue = new Mat();

    MatVector v = new MatVector(red, green, blue);
    split(image, v);

    //Run canny edge detection on each channel
    Mat blue_edges = new Mat();
    Canny(v.get(0), blue_edges, 200, 250);
    Mat green_edges = new Mat();
    Canny(v.get(1), green_edges, 200, 250);
    Mat red_edges = new Mat();
    Canny(v.get(2), red_edges, 200, 250);

    //Join edges back into image
    Mat edges = new Mat();
    MatVector vEdges = new MatVector(red_edges, green_edges, blue_edges);
    merge(vEdges, edges);
    LOGGER.info("Type: " + edges.type());


    //convert to grayscale
    Mat gray = new Mat();
    cvtColor(edges, gray, COLOR_BGR2GRAY);
    Mat blur = new Mat();
    GaussianBlur(gray, blur, new Size(5,5), 0);
    Mat edgesCopy = new Mat();
    adaptiveThreshold(blur, edgesCopy, 255,1,1,11,2);


    //Find the contours        
    Mat hierarchy = new Mat();
    MatVector contours = new MatVector();

    findContours(edgesCopy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);
s.ijpma
  • 822
  • 1
  • 11
  • 22