2013-03-27 26 views
17

Java Opencv-2.4.4 ve GUI ile bir uygulama geliştiriyorum. Sorun şu ki, herhangi bir çözüm bulamıyorum, bu da işlenmiş görüntünün (Mat nesnesinde kaydedilen) java swing GUI'ye nasıl yazdırılacağını gösterir. Bu an için bu hantal bir çözüm kullanıyorum:Opencv java - GUI'ye Resim Yükle

javax.swing.JLabel outputImage; 
outputImage.setIcon(new javax.swing.ImageIcon("/home/username/Output.png")); 

private void sliderStateChanged(javax.swing.event.ChangeEvent evt) { 
     . 
     . 
    Mat canny; // Here is saved what I want to plot 
    String filename = "/home/username/Output.png"; 
    Highgui.imwrite(filename, canny); // write to disk 
    outputImage.setIcon(new ImageIcon(ImageIO.read(new File(filename)))); //update Icon 
     . 
     . 
} 

kullanıcı Ben diskte Output.png üzerine ve diskten yeni görüntü ile JLabel güncellemek zorunda GUI bazı değerleri, girişleri vb değiştirir..

Bunun için daha zarif/verimli bir çözüm var mı? Mat nesnesini doğrudan Kanvas veya Resim ya da görüntü olarak yazdırılabilir şekilde basabilme özelliği var mı?

cevap

9

jpeg kodlama ilginç ama bir kaç sorun vardır:

  • öyle değil kayıpsız biçimi
  • o (uzunca bir süre alır sıkıştırarak kullanırken resmi verileri kaybedersiniz 6 ila 10 kat civarında aşağıda önerilen one) daha uzun
public Image toBufferedImage(Mat m){ 
     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 
     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; 

    } 
+0

sadece bir not: imencode() işlevinde ".png" yi de ayarlayabilirsiniz. Bu programcı ihtiyaçlarına bağlıdır, bu yüzden görüyorum – andriy

+0

bilgi kaybı yok. Sorun, çok uzun sürmesi. Yukarıdaki prosedür mümkün olan en hızlı şekilde yakındır. Sadece yerel belleğe işaret etmenin daha hızlı olacağına inanıyorum. – dannyxyz22

+0

Önerdiğim çözüm, görüntüyü GUI'ye yeterince hızlı yükleyecek, ancak yine de cevabınızı çok yardımcı buldum. OpenCV'de ve ImageJ'de ilk görüntüyü işlerken ve binlerce görüntü ile çalışırken bu tekniği (Mat'ı BufferedImage'a dönüştürürüm) kullanırım.Ve buradaki hız gerçekten önemlidir – andriy

14

Evet, bunu yapmanın daha zarif bir yolu var. Mat'ı BufferedImage türüne göre düzenleyebilir ve sonra sadece swing ile yükleyebilirsiniz.

Mat image_tmp = your image 

    MatOfByte matOfByte = new MatOfByte(); 

    Highgui.imencode(".jpg", image_tmp, matOfByte); 

    byte[] byteArray = matOfByte.toArray(); 
    BufferedImage bufImage = null; 

    try { 

     InputStream in = new ByteArrayInputStream(byteArray); 
     bufImage = ImageIO.read(in); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

Ve o zaman sadece GUI nesnesi içinde boyayabilirsiniz: Tamponlanmış görüntüye dönüştürmek için kod

gr bu yardımcı olur

Umut tipi Graphics'in olan

g.drawImage(bufImage , 0, 0, null); 

.

2

Bu hazır olduğunu Java OpenCV'de Imshow() eşdeğeri için çözüm Kullanımı basit. Tekrar disk içine görüntüyü depolamak ve okumaz gibi bu daha iyi bir çözümdür burada https://github.com/master-atul/ImShow-Java-OpenCV

Imshow im = new Imshow("Title"); 
im.showImage(matimage); 

Ziyaret: gibi API bakacağız. Bu nedenle, bir diskin okuma yükünü azaltır ve böylece daha hızlıdır.

+0

Merhaba MMD en \t, ben fikir gibi daha özlü bir Imshow sınıfı yapmak için her Swing GUI'sini kaydırma. Ben sadece benim yaklaşımımı showImage (Mat img) yönteminde kullanmanız gerektiğini düşünüyorum çünkü yaklaşık 5 kat daha hızlı. Sınıf için teşekkürler =) – dannyxyz22

+0

Yorum için teşekkürler ... Ben dahil edeceğiz ... – Atul

1

@ andriy's anwser öğesini kullanarak. Bu çözümle geldim. Grafik yerine JFrame kullandım. Bu yardımcı olur umarım.

public void imshow(Mat src){ 
    BufferedImage bufImage = null; 
    try { 
     MatOfByte matOfByte = new MatOfByte(); 
     Highgui.imencode(".jpg", src, matOfByte); 
     byte[] byteArray = matOfByte.toArray(); 
     InputStream in = new ByteArrayInputStream(byteArray); 
     bufImage = ImageIO.read(in); 

     JFrame frame = new JFrame("Image"); 
     frame.getContentPane().setLayout(new FlowLayout()); 
     frame.getContentPane().add(new JLabel(new ImageIcon(bufImage))); 
     frame.pack(); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
}