Unsupported format or combination of formats (Only 8-bit, 3-channel input images are supported) in cvWatershed

StackOverflow https://stackoverflow.com/questions/16371368

Question

Hi I am new to image segmentation, i am trying the given code to get foreground objects, but i got error like "Unsupported format or combination of formats (Only 8-bit, 3-channel input images are supported) in cvWatershed"

cv::Mat img0 = [img toMat];
cv::Mat img1;
cv::cvtColor(img0, img0, CV_RGB2GRAY);
cv::threshold(img0, img0, 100, 255, cv::THRESH_BINARY);

cv::Mat fg;
cv::erode(img0,fg,cv::Mat(),cv::Point(-1,-1),6);

cv::Mat bg;
cv::dilate(img0,bg,cv::Mat(),cv::Point(-1,-1),6);
cv::threshold(bg,bg,1,128,cv::THRESH_BINARY_INV);

cv::Mat markers(img0.size(),CV_8U,cv::Scalar(0));
markers= fg+bg;

// cv::namedWindow("Markers"); // cv::imshow("Markers", markers);

WatershedSegmenter segmenter;
segmenter.setMarkers(markers);
cv::Mat result1 = segmenter.process(img0);

// cv::Mat result1; result1.convertTo(result1,CV_8U);

UIImage * result = [UIImage imageWithMat:result1 andImageOrientation:[img imageOrientation]];
return result;

And i try by debugging and got error in line

cv::Mat result1 = segmenter.process(img0);

Thanks in advance

Was it helpful?

Solution

I again analyzed my code and solved the problem. Convert the image to ilpImage and then change it to a 8 bit and 3 channel image using code

WatershedSegmenter segmenter;
segmenter.setMarkers(markers);
markers=cvCreateImage(cvGetSize(my_iplImage), IPL_DEPTH_8U, 3);
cv::Mat result1 = segmenter.process(markers);

OTHER TIPS

This reminds me on one example from book "Opencv 2 computer vision application programming cookbook". All you should do was to do this:

// Get the binary map
    cv::Mat binary;
    //binary = cv::imread("binary.bmp", 0); // prevent loading of pre-converted image
    cvtColor(image, binary, CV_BGR2GRAY); // instead convert original
    binary = binary < 65; // apply threshold

Whole code (excluding water segmentation header) would be something like this:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "watershedSegmentation.h"

int main()
{
    // Read input image
    cv::Mat image = cv::imread("group.jpg");
    if (!image.data)
        return 0;

    // Display the image
    cv::namedWindow("Original Image");
    cv::imshow("Original Image", image);

//  // Get the binary map
    cv::Mat binary;
    //binary = cv::imread("binary.bmp", 0); // prevent loading of pre-converted image
    cvtColor(image, binary, CV_BGR2GRAY); // instead convert original
    binary = binary < 60; // apply threshold

    // Display the binary image
    cv::namedWindow("Binary Image");
    cv::imshow("Binary Image", binary);

    // Eliminate noise and smaller objects
    cv::Mat fg;
    cv::erode(binary, fg, cv::Mat(), cv::Point(-1, -1), 6);

    // Display the foreground image
    cv::namedWindow("Foreground Image");
    cv::imshow("Foreground Image", fg);

    // Identify image pixels without objects
    cv::Mat bg;
    cv::dilate(binary, bg, cv::Mat(), cv::Point(-1, -1), 6);
    cv::threshold(bg, bg, 1, 128, cv::THRESH_BINARY_INV);

    // Display the background image
    cv::namedWindow("Background Image");
    cv::imshow("Background Image", bg);

    // Show markers image
    cv::Mat markers(binary.size(), CV_8U, cv::Scalar(0));
    markers = fg + bg;
    cv::namedWindow("Markers");
    cv::imshow("Markers", markers);

    // Create watershed segmentation object
    WatershedSegmenter segmenter;
    // Set markers and process
    segmenter.setMarkers(markers);
    segmenter.process(image);

    // Display segmentation result
    cv::namedWindow("Segmentation");
    cv::imshow("Segmentation", segmenter.getSegmentation());

    // Display watersheds
    cv::namedWindow("Watersheds");
    cv::imshow("Watersheds", segmenter.getWatersheds());

    cv::waitKey();
    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top