wpf frame page 越来越多_opencv更多图形变换

本文详细介绍了如何在WPF Frame Page中应用OpenCV进行图像处理,包括开运算、闭运算、形态学梯度、顶帽和黑帽等图形变换操作。通过Java实现,利用opencv-410版本,展示了各种变换前后图像的效果,旨在学习和理解这些图像处理技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0622a2523e194122375961b15521abda.png

本文目的

目的:学习使用opencv的更多图形变化操作
语言:java
版本:opencv-410
简介:使用morphologyEx(Mat src, Mat dst, int op, Mat kernel)进行更多图像变换

分解介绍

  • MORPH_OPEN – 开运算(Opening operation)
    先腐蚀,再膨胀,可清除一些小东西(亮的),放大局部低亮度的区域 效果如下:左侧的小亮点,通过开运算后就消除掉了

0a3fc69ab6724b9986374f4320ee5260.png
  • MORPH_CLOSE – 闭运算(Closing operation)
    先膨胀,再腐蚀,可清除小黑点 效果如下:左侧的小黑点,通过闭运算后就消除掉了

bdee3dad71b7679795badb4466a081b7.png
  • MORPH_GRADIENT -形态学梯度(Morphological gradient)
    膨胀图与腐蚀图之差,提取物体边缘
  • MORPH_TOPHAT - “顶帽”(“Top hat”)
    原图像-开运算图,突出原图像中比周围亮的区域
  • MORPH_BLACKHAT - “黑帽”(“Black hat“)
    闭运算图-原图像,突出原图像中比周围暗的区域

代码

package com.joe.vision.machine.vision.samples;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.springframework.util.ResourceUtils;

public class MorphologyDemo2 {
    private static final String[] MORPH_OP = { "Opening", "Closing", "Gradient", "Top Hat", "Black Hat" };
    private static final int[] MORPH_OP_TYPE = { Imgproc.MORPH_OPEN, Imgproc.MORPH_CLOSE,
            Imgproc.MORPH_GRADIENT, Imgproc.MORPH_TOPHAT, Imgproc.MORPH_BLACKHAT };
    private static final String[] ELEMENT_TYPE = { "Rectangle", "Cross", "Ellipse" };
    private static final int MAX_KERNEL_SIZE = 21;
    private Mat matImgSrc;
    private Mat matImgDst = new Mat();
    private int morphOpType = Imgproc.MORPH_OPEN;
    private int elementType = Imgproc.CV_SHAPE_RECT;
    private int kernelSize = 0;
    private JFrame frame;
    private JLabel imgLabel;
    public MorphologyDemo2(String[] args) throws FileNotFoundException {
        String imagePath = getFilePath("static/time.jpg");
        matImgSrc = Imgcodecs.imread(imagePath);
        if (matImgSrc.empty()) {
            System.out.println("Empty image: " + imagePath);
            System.exit(0);
        }
        // Create and set up the window.
        frame = new JFrame("Morphology Transformations demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Set up the content pane.
        Image img = HighGui.toBufferedImage(matImgSrc);
        addComponentsToPane(frame.getContentPane(), img);
        // Use the content pane's default BorderLayout. No need for
        // setLayout(new BorderLayout());
        // Display the window.
        frame.pack();
        frame.setVisible(true);
    }
    private void addComponentsToPane(Container pane, Image img) {
        if (!(pane.getLayout() instanceof BorderLayout)) {
            pane.add(new JLabel("Container doesn't use BorderLayout!"));
            return;
        }
        JPanel sliderPanel = new JPanel();
        sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));

        //构造操作类型下拉框
        JComboBox<String> morphOpBox = buildOpBox();
        //构造处理的元素类型
        JComboBox<String> elementTypeBox = buildElementType();
        //构造滑动工具条
        JSlider slider = buildSlider();

        sliderPanel.add(morphOpBox);
        sliderPanel.add(elementTypeBox);
        sliderPanel.add(new JLabel("内核尺寸: 2n + 1"));
        sliderPanel.add(slider);

        pane.add(sliderPanel, BorderLayout.PAGE_START);
        imgLabel = new JLabel(new ImageIcon(img));
        pane.add(imgLabel, BorderLayout.CENTER);
    }

    private JComboBox<String> buildOpBox() {
        JComboBox<String> morphOpBox = new JComboBox<>(MORPH_OP);
        morphOpBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                @SuppressWarnings("unchecked")
                JComboBox<String> cb = (JComboBox<String>)e.getSource();
                morphOpType = MORPH_OP_TYPE[cb.getSelectedIndex()];
                update();
            }
        });
        return morphOpBox;
    }

    private JSlider buildSlider() {
        JSlider slider = new JSlider(0, MAX_KERNEL_SIZE, 0);
        slider.setMajorTickSpacing(5);
        slider.setMinorTickSpacing(5);
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);
        slider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                JSlider source = (JSlider) e.getSource();
                kernelSize = source.getValue();
                update();
            }
        });
        return slider;
    }

    private JComboBox<String> buildElementType() {
        JComboBox<String> elementTypeBox = new JComboBox<>(ELEMENT_TYPE);
        elementTypeBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                @SuppressWarnings("unchecked")
                JComboBox<String> cb = (JComboBox<String>)e.getSource();
                if (cb.getSelectedIndex() == 0) {
                    elementType = Imgproc.CV_SHAPE_RECT;
                } else if (cb.getSelectedIndex() == 1) {
                    elementType = Imgproc.CV_SHAPE_CROSS;
                } else if (cb.getSelectedIndex() == 2) {
                    elementType = Imgproc.CV_SHAPE_ELLIPSE;
                }
                update();
            }
        });
        return elementTypeBox;
    }

    private void update() {
        Mat element = Imgproc.getStructuringElement(elementType, new Size(2 * kernelSize + 1, 2 * kernelSize + 1),
                new Point(kernelSize, kernelSize));
        Imgproc.morphologyEx(matImgSrc, matImgDst, morphOpType, element);
        Image img = HighGui.toBufferedImage(matImgDst);
        imgLabel.setIcon(new ImageIcon(img));
        frame.repaint();
    }

    public String getFilePath(String filename) throws FileNotFoundException {
        File file = ResourceUtils.getFile(filename);
        return file.getAbsolutePath();
    }

    public static void main(String[] args) {
        // Load the native OpenCV library
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        // Schedule a job for the event dispatch thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    new MorphologyDemo2(args);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

效果图

本程序原图:

4e89d999f4c98685193d6a14be6a17d8.png

开运算结果:是不是放大了低亮度区域

f6ea9dd72b5393529c789eba4593e8a6.png

闭运算结果:是不是消除了部分小黑点

69895f18f7e4eb799ecc0bc13aad71d5.png

形态学变换后效果:

8083b42d548dec3c4ef8a25a6a49c83e.png

顶帽操作效果:原图-开运算结果

13de9076de12a3f9f45af2ca557dd792.png

黑帽操作效果:闭运算图-原图像

993cf3f1afce9a151e5a467f2132fdbe.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值