OpenCV [模板匹配]" java.lang.UnsupportedOperationException:Mat数据类型不兼容:5"

时间:2017-04-20 14:05:55

标签: java opencv

OpenCV官方演示[模板匹配] [MatchTemplate_Demo.cpp]

http://docs.opencv.org/3.2.0/de/da9/tutorial_template_matching.html

我是用java写的。

MatchTemplateDemo.java

package Histogram_Matching;

import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import util.Highgui;

class MatchTemplateDemoOperationsRun {

    boolean use_mask;
    Mat img;
    Mat templ;
    Mat mask;
    Mat result = new Mat();
    final String image_window = "Source Image";
    final String result_window = "Result window";

    int match_method;
    int max_Trackbar = 5;

    void run() {
        img = Imgcodecs.imread("./res/Template_Matching_Original_Image.jpg", Imgcodecs.IMREAD_COLOR);
        templ = Imgcodecs.imread("./res/Template_Matching_Template_Image.jpg", Imgcodecs.IMREAD_COLOR);

//      Highgui.imshow("img", img);
//      Highgui.imshow("templ", templ);

        // use_mask = true;
        // mask = Imgcodecs.imread("", Imgcodecs.IMREAD_COLOR);

        Highgui.namedWindow(image_window, Highgui.WINDOW_AUTOSIZE);
        Highgui.namedWindow(result_window, Highgui.WINDOW_AUTOSIZE);

        final String trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";
        Highgui.createTrackbar(trackbar_label, image_window, max_Trackbar, new Highgui.TrackbarCallback() {

            @Override
            public void onChange(int i) {
                match_method = i;
                MatchingMethod(i);
            }
        });

        MatchingMethod(0);
    }

    void MatchingMethod(int value) {
        Mat img_display = new Mat();
        img.copyTo(img_display);

        int result_cols = img.cols() - templ.cols() + 1;
        int result_rows = img.rows() - templ.rows() + 1;

        result.create(result_rows, result_cols, CvType.CV_32FC1);

        boolean method_accepts_mask = (Imgproc.TM_SQDIFF == match_method || match_method == Imgproc.TM_CCORR_NORMED);
        if (use_mask && method_accepts_mask) {
            Imgproc.matchTemplate(img, templ, result, match_method, mask);
        } else {
            Imgproc.matchTemplate(img, templ, result, match_method);
        }

        Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());

        // double minVal;
        // double maxVal;
        // Point minLoc;
        // Point maxLoc;
        MinMaxLocResult res;
        Point matchLoc;

        res = Core.minMaxLoc(result, new Mat());

        if (match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED) {
            matchLoc = res.minLoc;
        } else {
            matchLoc = res.maxLoc;
        }

        Imgproc.rectangle(img_display, matchLoc, new Point(matchLoc.x + templ.cols(), matchLoc.y + templ.rows()),
                Scalar.all(0), 2, Imgproc.LINE_8, 0);
        Imgproc.rectangle(result, matchLoc, new Point(matchLoc.x + templ.cols(), matchLoc.y + templ.rows()),
                Scalar.all(0), 2, Imgproc.LINE_8, 0);

        Highgui.imshow(image_window, img_display);
        Highgui.imshow(result_window, result); // HERE!!!!!!
    }
}

public class MatchTemplateDemo {

    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        new MatchTemplateDemoOperationsRun().run();
    }

}

Highgui.imshow():核心方法是

private static Image toBufferedImage(Mat m) {

    System.out.println("m.channels():" + m.channels());
    System.out.println("m.dump():" + m.dump());

    int type = BufferedImage.TYPE_BYTE_GRAY;
    if (m.channels() > 1) {
        type = BufferedImage.TYPE_3BYTE_BGR;
    }
    int bufferSize = m.channels() * m.cols() * m.rows();
    byte[] b = new byte[bufferSize];
    m.get(0, 0, b); // get all the pixels // !!!HERE!!!
    BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
    final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
    System.arraycopy(b, 0, targetPixels, 0, b.length);
    return image;
}

OpenCV没有Highgui util,所以我写了一个简单的Highgui.java:
注意!!!这里!!!评论!!!

Highgui.java

package util;

import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;

import javax.swing.ImageIcon;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.opencv.core.Mat;

public class Highgui {

    public static final int WINDOW_NORMAL = 0;
    public static int WINDOW_AUTOSIZE = -1;

    static Map<String, Window> windows = new HashMap<>();

    static Window getWindow(String windowname) {
        Window window = windows.get(windowname);
        if (window == null) {
            window = new Window();
            window.addKeyListener(keyListnere);
            window.setVisible(true);

            windows.put(windowname, window);
        }

        return window;
    }

    public static void namedWindow(String title, int size) {
        Window window = getWindow(title);

        window.setWindowName(title);
    }

    public static void imshow(String title, Mat mat) {

        Window window = getWindow(title);

        ImageIcon icon = new ImageIcon(toBufferedImage(mat));
        window.setIcon(icon);
    }

    public static void moveWindow(String title, int x, int y) {
        Window window = getWindow(title);

        window.setLocation(x, y);
    }

    public static void createTrackbar(String trackbarname, String winname, int count, TrackbarCallback callback) {
        Window window = getWindow(winname);

        window.createTrackbar(trackbarname, count, new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                if (callback != null) {
                    JSlider slider = (JSlider) e.getSource();
                    callback.onChange(slider.getValue());
                }
            }
        });
    }

    public interface TrackbarCallback {
        void onChange(int i);
    }

    public interface MouseCallback {
        void onMouse(int event, int x, int y, int flags);
    }

    private static Image toBufferedImage(Mat m) {

        System.out.println("m.channels():" + m.channels());
        System.out.println("m.dump():" + m.dump());

        int type = BufferedImage.TYPE_BYTE_GRAY;
        if (m.channels() > 1) {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
        int bufferSize = m.channels() * m.cols() * m.rows();
        byte[] b = new byte[bufferSize];
        m.get(0, 0, b); // get all the pixels // !!!HERE!!!
        BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
        final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        System.arraycopy(b, 0, targetPixels, 0, b.length);
        return image;
    }

//  private static BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(1024);
    private static Queue<Integer> keys = new PriorityQueue<>();

    public static int waitKey(int delay) {

        long start = System.currentTimeMillis();

        for (;;) {

            long current = System.currentTimeMillis();

            if (delay > 0 && current - start > delay) {
                return -1;
            }


            Integer poll = keys.poll();

            if (poll != null) {
                return (int) poll;
            }

            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // return -1;
    }

    private static KeyListener keyListnere = new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
            System.out.println("keyTyped() e: " + e);
        }

        @Override
        public void keyReleased(KeyEvent e) {
            System.out.println("keyReleased() e: " + e);
        }

        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println("keyPressed() e: " + e);

            keys.add((int) e.getKeyChar());
        }
    };

    public static void setTrackbarPos(String trackbarname, String winname, int pos) {
        Window window = getWindow(winname);
//      window.getFrame().revalidate();
//      window.getFrame().repaint();        
    }

    public static void setMouseCallback(String winname, MouseCallback onMouse) {
        Window window = getWindow(winname);
    }
}

控制台

Exception in thread "main" java.lang.UnsupportedOperationException: Mat data type is not compatible: 5
    at org.opencv.core.Mat.get(Mat.java:1015)
    at util.Highgui.toBufferedImage(Highgui.java:98)
    at util.Highgui.imshow(Highgui.java:54)
    at Histogram_Matching.MatchTemplateDemoOperationsRun.MatchingMethod(MatchTemplateDemo.java:92)
    at Histogram_Matching.MatchTemplateDemoOperationsRun.run(MatchTemplateDemo.java:50)
    at Histogram_Matching.MatchTemplateDemo.main(MatchTemplateDemo.java:100)

Highgui.toBufferedImage()有问题,它是从opencv的java演示版中复制的,但是当它通过&#39;结果&#39时,它在这里不能正常工作;相信它。

at org.opencv.core.Mat.get(Mat.java:1015)
at util.Highgui.toBufferedImage(Highgui.java:98)

(Highgui.java:98)在Highgui.toBufferedImage()中:

m.get(0, 0, b); // get all the pixels

0 个答案:

没有答案