3

嗨,我是图像分割的新手,我正在尝试使用给定的代码来获取前景对象,但出现错误,例如“cvWatershed 中不支持的格式或格式组合(仅支持 8 位、3 通道输入图像)”

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("标记", 标记);

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;

我尝试通过调试并在线出错

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

提前致谢

4

2 回答 2

2

我再次分析了我的代码并解决了问题。将图像转换为 ilpImage,然后使用代码将其更改为 8 位和 3 通道图像

WatershedSegmenter segmenter;
segmenter.setMarkers(markers);
markers=cvCreateImage(cvGetSize(my_iplImage), IPL_DEPTH_8U, 3);
cv::Mat result1 = segmenter.process(markers);
于 2013-05-17T06:30:56.797 回答
0

这让我想起了“Opencv 2 计算机视觉应用程序编程食谱”一书中的一个例子。你应该做的就是这样做:

// 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

整个代码(不包括水分割头)将是这样的:

#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;
}
于 2013-07-24T07:43:13.770 回答