我正在尝试查找符号的轮廓。我几乎可以正常工作,这是第一个测试图像:
但是,在第二张测试图像中,我只能找到一个轮廓:
这是我的代码:
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.util.ArrayList;
public class FilteOpenCV {
public static final Scalar COLOR_WHITE = colorRGB(255, 255, 255);
public static final Scalar COLOR_BLUE = colorRGB(0, 0, 255);
public static Scalar colorRGB(double red, double green, double blue) {
return new Scalar(blue, green, red);
}
//получаем BufferedImage
public static BufferedImage MatToBufferedImage(Mat m) {
if (m == null || m.empty()) return null;
if (m.depth() == CvType.CV_8U) {
} else if (m.depth() == CvType.CV_16U) { // CV_16U => CV_8U
Mat m_16 = new Mat();
m.convertTo(m_16, CvType.CV_8U, 255.0 / 65535);
m = m_16;
} else if (m.depth() == CvType.CV_32F) { // CV_32F => CV_8U
Mat m_32 = new Mat();
m.convertTo(m_32, CvType.CV_8U, 255);
m = m_32;
} else
return null;
int type = 0;
if (m.channels() == 1)
type = BufferedImage.TYPE_BYTE_GRAY;
else if (m.channels() == 3)
type = BufferedImage.TYPE_3BYTE_BGR;
else if (m.channels() == 4)
type = BufferedImage.TYPE_4BYTE_ABGR;
else
return null;
byte[] buf = new byte[m.channels() * m.cols() * m.rows()];
m.get(0, 0, buf);
byte tmp = 0;
if (m.channels() == 4) { // BGRA => ABGR
for (int i = 0; i < buf.length; i += 4) {
tmp = buf[i + 3];
buf[i + 3] = buf[i + 2];
buf[i + 2] = buf[i + 1];
buf[i + 1] = buf[i];
buf[i] = tmp;
}
}
BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
byte[] data =
((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(buf, 0, data, 0, buf.length);
return image;
}
//показываем изображение
public static void showImage(Mat img, String title) {
BufferedImage im = MatToBufferedImage(img);
if (im == null) return;
int w = 1000, h = 600;
JFrame window = new JFrame(title);
window.setSize(w, h);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon imageIcon = new ImageIcon(im);
JLabel label = new JLabel(imageIcon);
JScrollPane pane = new JScrollPane(label);
window.setContentPane(pane);
if (im.getWidth() < w && im.getHeight() < h) {
window.pack();
}
window.setLocationRelativeTo(null);
window.setVisible(true);
}
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat img = Imgcodecs.imread("C:\\Users\\dennn\\PycharmProjects\\untitled2\\imag\\output11.jpg"); //считываем
if (img.empty()) {
System.out.println("Не удалось загрузить изображение");
return;
}
showImage(img, "Оригинал");
Mat imgGray = new Mat();
Imgproc.cvtColor(img, imgGray, Imgproc.COLOR_BGR2GRAY);
Mat edges = new Mat();
Imgproc.Canny(imgGray, edges, 80, 200);
Mat edgesCopy = edges.clone(); // Создаем копию
ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(edgesCopy, contours, new Mat(),
Imgproc.RETR_EXTERNAL,
Imgproc.CHAIN_APPROX_SIMPLE);
for (int i = 0, j = contours.size(); i < j; i++) {
System.out.println(Imgproc.contourArea(contours.get(i)));
Rect r = Imgproc.boundingRect(contours.get(i));
System.out.println("boundingRect = " + r);
double len = Imgproc.arcLength(
new MatOfPoint2f(contours.get(i).toArray()), true);
System.out.println("arcLength = " + len);
Imgproc.rectangle(img, new Point(r.x, r.y),
new Point(r.x + r.width - 1, r.y + r.height - 1),
COLOR_BLUE);
}
showImage(img, "boundingRect");
img.release(); imgGray.release();
edges.release(); edgesCopy.release();
}
}
我不明白为什么我只能在第二张图像中找到一个轮廓。我怎么解决这个问题?任何帮助表示赞赏。