OpenCv图像转换

时间:2011-12-06 17:46:33

标签: java image-processing opencv

尝试使用分水岭方法时出现此错误:Unsupported format or combination of formats (Only 32-bit, 1-channel output images are supported) in cvWatershed

我认为这是因为我的标记有3个通道,深度为8.我想我需要将这个3通道8深度图像转换为32位1通道图像。我的问题是我是对的吗?以及如何进行此转换?

编辑:使用解决方案更新了代码

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kitouch;

import org.OpenNI.*;
import com.googlecode.javacpp.Loader;
import com.googlecode.javacv.*;
import com.googlecode.javacv.cpp.*;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_calib3d.*;
import static com.googlecode.javacv.cpp.opencv_objdetect.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
import java.nio.ShortBuffer;
import java.awt.*;
import java.awt.image.*;

/**
 *
 * @author olivierjanssens
 */
public class watherShedExample {


   // CanvasFrame frame5 = new CanvasFrame("Some T");
    public static void main(String s[])
    {
    CanvasFrame frame1 = new CanvasFrame("Foreground");
    CanvasFrame frame2 = new CanvasFrame("Dilated");
    CanvasFrame frame3 = new CanvasFrame("Background");
    CanvasFrame frame4 = new CanvasFrame("Markers");
    CanvasFrame frame5 = new CanvasFrame("Watershed");
        // Read input image
    IplImage image = cvLoadImage("/Users/olivierjanssens/Downloads/images/group.jpg");
    IplImage test = cvLoadImage("/Users/olivierjanssens/Downloads/images/binary.bmp");

    IplImage binary = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
     cvCvtColor(test, binary, CV_BGR2GRAY);

    // Eliminate noise and smaller objects, repeat erosion 6 times
    IplImage fg = cvCreateImage(cvGetSize(binary), binary.depth(), binary.nChannels() /* channels */);
    cvErode(binary, fg, null /* 3x3 square */ , 6 /* iterations */);
    frame1.showImage(fg);


    // Identify image pixels pixels objects
    IplImage bg = cvCreateImage(cvGetSize(binary), binary.depth(), binary.nChannels() /* channels */);
    cvDilate(binary, bg, null /* 3x3 square */ , 6 /* iterations */);
    frame2.showImage(bg);

    cvThreshold(bg, bg, 1 /* threshold */ , 128 /* max value */ , CV_THRESH_BINARY_INV);
    frame3.showImage(bg);

    // Create marker image
    IplImage markers = cvCreateImage(cvGetSize(binary), IPL_DEPTH_8U, binary.nChannels() /* channels */);
    cvAdd(fg, bg, markers, null);
    frame4.showImage(markers);
/*
     * TEST SOLUTION 1
    IplImage gray = cvCreateImage(cvGetSize(markers), IPL_DEPTH_8U, 1); 
    cvCvtColor(markers, gray, CV_BGR2GRAY);

    IplImage img32bit1chan = cvCreateImage(cvGetSize(gray), IPL_DEPTH_32F, 1);

    double ve;
    for (int i = 0; i < gray.width(); i++) // markers width
    {
       for (int j = 0; j < gray.height(); j++) // markers height
       {
           ve = cvGetReal2D((IplImage)gray, j, i); 
           cvSetReal2D((IplImage)img32bit1chan , i, j, ve);
       }
    }
*/

    //SOLUTION 2 
    IplImage markers32f = cvCreateImage(cvGetSize(binary), IPL_DEPTH_32F, binary.nChannels());
    cvConvertScale(markers, markers32f, 1, 0); // converts from IPL_DEPTH_8U to IPL_DEPTH_32F


    cvWatershed(image, markers32f);

    frame5.showImage(image);

    }
}

2 个答案:

答案 0 :(得分:1)

我不熟悉Java API,但您可以采用以下方式:

IplImage image = cvLoadImage("/Users/olivierjanssens/Downloads/images/group.jpg");

// this will force the image to be read as grayscale (i.e. single channel)
// sometimes saving a "binary" bitmap will result in a 3 channel image
IplImage binary = cvLoadImage("/Users/olivierjanssens/Downloads/images/binary.bmp", 0);

...

IplImage markers = cvCreateImage(cvGetSize(binary), IPL_DEPTH_8U, binary.nChannels() /* channels */);
cvAdd(fg, bg, markers, null);
frame4.showImage(markers);

IplImage markers32f = cvCreateImage(cvGetSize(binary), IPL_DEPTH_32F, binary.nChannels());
cvConvertScale(markers, markers32f, 1, 0); // converts from IPL_DEPTH_8U to IPL_DEPTH_32F

cvWatershed(image, markers32f);

看看它是否适合你。

答案 1 :(得分:1)

手动转换看起来如下(尚未测试代码):

IplImage gray = cvCreateImage(cvGetSize(markers), IPL_DEPTH_8U, 1); 
cvCvtColor(markers, gray, CV_BGR2GRAY);

IplImage img32bit1chan = cvCreateImage(cvGetSize(gray), IPL_DEPTH_32S, 1);

// convert 8-bit 1-channel image to 32-bit 1-channel
cvConvertScale(gray, img32bit1chan , 1/255.);

cvWatershed(image, img32bit1chan);