javaCV圖像處理之Frame、Mat和IplImage三者相互轉換(使用openCV進行Mat和IplImage轉換)


前言:本篇文章依賴四個jar包,其中javacv.jar,javacpp.jar和opencv.jar為固定jar包,opencv-系統環境.jar為選配(根據自己的系統平台,x64還是x86而定)

須知:

OpenCVFrameConverter.ToIplImage可以用於將Frame轉換為Mat和IplImage,Mat和IplImage轉為Frame

Mat和IplImage之間的轉換可以使用opeoCV庫中提供的功能


使用方式:

static OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();

public static void converter(Frame frame) {
		
		// 將Frame轉為Mat
		Mat mat = converter.convertToMat(frame);
		
		// 將Mat轉為Frame
		Frame convertFrame1 = converter.convert(mat);
		
		// 將Frame轉為IplImage
		IplImage image1 = converter.convertToIplImage(frame);
		IplImage image2 = converter.convert(frame);
		
		// 將IplImage轉為Frame
		Frame convertFrame2 = converter.convert(image1);
		
		//Mat轉IplImage
		IplImage matImage = new IplImage(mat);
		
		//IplImage轉Mat
		Mat mat2 = new Mat(matImage);

	}

測試:

public static void main(String[] args) throws Exception {
		// 抓取取本機攝像頭
		OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
		grabber.start();
		//取一幀視頻(圖像)
		converter(grabber.grab());
		grabber.stop();
	}


源碼一覽:


/**
 * A utility class to map data between {@link Frame} and {@link IplImage} or {@link Mat}.
 * Since this is an abstract class, one must choose between two concrete classes:
 * {@link ToIplImage} or {@link ToMat}.
 *
 * @author Samuel Audet
 */
public abstract class OpenCVFrameConverter<F> extends FrameConverter<F> {
    IplImage img;
    Mat mat;

    public static class ToIplImage extends OpenCVFrameConverter<IplImage> {
        @Override public Frame convert(IplImage img) { return super.convert(img); }
        @Override public IplImage convert(Frame frame) { return convertToIplImage(frame); }
    }

    public static class ToMat extends OpenCVFrameConverter<Mat> {
        @Override public Frame convert(Mat mat) { return super.convert(mat); }
        @Override public Mat convert(Frame frame) { return convertToMat(frame); }
    }

    public static int getFrameDepth(int depth) {
        switch (depth) {
            case IPL_DEPTH_8U:  case CV_8U:  return Frame.DEPTH_UBYTE;
            case IPL_DEPTH_8S:  case CV_8S:  return Frame.DEPTH_BYTE;
            case IPL_DEPTH_16U: case CV_16U: return Frame.DEPTH_USHORT;
            case IPL_DEPTH_16S: case CV_16S: return Frame.DEPTH_SHORT;
            case IPL_DEPTH_32F: case CV_32F: return Frame.DEPTH_FLOAT;
            case IPL_DEPTH_32S: case CV_32S: return Frame.DEPTH_INT;
            case IPL_DEPTH_64F: case CV_64F: return Frame.DEPTH_DOUBLE;
            default: return -1;
        }
    }

    public static int getIplImageDepth(int depth) {
        switch (depth) {
            case Frame.DEPTH_UBYTE:  return IPL_DEPTH_8U;
            case Frame.DEPTH_BYTE:   return IPL_DEPTH_8S;
            case Frame.DEPTH_USHORT: return IPL_DEPTH_16U;
            case Frame.DEPTH_SHORT:  return IPL_DEPTH_16S;
            case Frame.DEPTH_FLOAT:  return IPL_DEPTH_32F;
            case Frame.DEPTH_INT:    return IPL_DEPTH_32S;
            case Frame.DEPTH_DOUBLE: return IPL_DEPTH_64F;
            default:  return -1;
        }
    }
    static boolean isEqual(Frame frame, IplImage img) {
        return img != null && frame != null && frame.image != null && frame.image.length > 0
                && frame.imageWidth == img.width() && frame.imageHeight == img.height()
                && frame.imageChannels == img.nChannels() && getIplImageDepth(frame.imageDepth) == img.depth()
                && new Pointer(frame.image[0]).address() == img.imageData().address()
                && frame.imageStride * Math.abs(frame.imageDepth) / 8 == img.widthStep();
    }
    public IplImage convertToIplImage(Frame frame) {
        if (frame == null || frame.image == null) {
            return null;
        } else if (frame.opaque instanceof IplImage) {
            return (IplImage)frame.opaque;
        } else if (!isEqual(frame, img)) {
            int depth = getIplImageDepth(frame.imageDepth);
            img = depth < 0 ? null : IplImage.createHeader(frame.imageWidth, frame.imageHeight, depth, frame.imageChannels)
                    .imageData(new BytePointer(new Pointer(frame.image[0].position(0))))
                    .widthStep(frame.imageStride * Math.abs(frame.imageDepth) / 8)
                    .imageSize(frame.image[0].capacity() * Math.abs(frame.imageDepth) / 8);
        }
        return img;
    }
    public Frame convert(IplImage img) {
        if (img == null) {
            return null;
        } else if (!isEqual(frame, img)) {
            frame = new Frame();
            frame.imageWidth = img.width();
            frame.imageHeight = img.height();
            frame.imageDepth = getFrameDepth(img.depth());
            frame.imageChannels = img.nChannels();
            frame.imageStride = img.widthStep() * 8 / Math.abs(frame.imageDepth);
            frame.image = new Buffer[] { img.createBuffer() };
            frame.opaque = img;
        }
        return frame;
    }

    public static int getMatDepth(int depth) {
        switch (depth) {
            case Frame.DEPTH_UBYTE:  return CV_8U;
            case Frame.DEPTH_BYTE:   return CV_8S;
            case Frame.DEPTH_USHORT: return CV_16U;
            case Frame.DEPTH_SHORT:  return CV_16S;
            case Frame.DEPTH_FLOAT:  return CV_32F;
            case Frame.DEPTH_INT:    return CV_32S;
            case Frame.DEPTH_DOUBLE: return CV_64F;
            default:  return -1;
        }
    }
    static boolean isEqual(Frame frame, Mat mat) {
        return mat != null && frame != null && frame.image != null && frame.image.length > 0
                && frame.imageWidth == mat.cols() && frame.imageHeight == mat.rows()
                && frame.imageChannels == mat.channels() && getMatDepth(frame.imageDepth) == mat.depth()
                && new Pointer(frame.image[0]).address() == mat.data().address()
                && frame.imageStride * Math.abs(frame.imageDepth) / 8 == (int)mat.step();
    }
    public Mat convertToMat(Frame frame) {
        if (frame == null || frame.image == null) {
            return null;
        } else if (frame.opaque instanceof Mat) {
            return (Mat)frame.opaque;
        } else if (!isEqual(frame, mat)) {
            int depth = getMatDepth(frame.imageDepth);
            mat = depth < 0 ? null : new Mat(frame.imageHeight, frame.imageWidth, CV_MAKETYPE(depth, frame.imageChannels),
                    new Pointer(frame.image[0].position(0)), frame.imageStride * Math.abs(frame.imageDepth) / 8);
        }
        return mat;
    }
    public Frame convert(Mat mat) {
        if (mat == null) {
            return null;
        } else if (!isEqual(frame, mat)) {
            frame = new Frame();
            frame.imageWidth = mat.cols();
            frame.imageHeight = mat.rows();
            frame.imageDepth = getFrameDepth(mat.depth());
            frame.imageChannels = mat.channels();
            frame.imageStride = (int)mat.step() * 8 / Math.abs(frame.imageDepth);
            frame.image = new Buffer[] { mat.createBuffer() };
            frame.opaque = mat;
        }
        return frame;
    }
}












免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM