zoukankan      html  css  js  c++  java
  • 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;
        }
    }











  • 相关阅读:
    C# 设计模式
    FutureTask、Fork/Join、 BlockingQueue
    线程的几种创建方式
    行锁、表锁、乐观锁、悲观锁
    J.U.C之AQS
    同步容器并发容器
    线程不安全类
    线程封闭
    不可变对象
    安全发布对象—单例模式
  • 原文地址:https://www.cnblogs.com/eguid/p/10195594.html
Copyright © 2011-2022 走看看