2013-03-27 3 views
17

मैं जावा ओपनसीवी-2.4.4 और स्विंग जीयूआई का उपयोग कर एक एप्लीकेशन विकसित कर रहा हूं। समस्या यह है कि मैं कोई समाधान नहीं ढूंढ पा रहा हूं, जो जावा स्विंग जीयूआई में संसाधित छवि को प्रिंट करने के तरीके को प्रभावी तरीके से दिखाता है (मैट ऑब्जेक्ट में सहेजा गया)। इस पल के लिए मैं इस अनाड़ी समाधान का उपयोग कर रहा:ओपनसीवी जावा - लोड छवि को जीयूआई

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 
     . 
     . 
} 

उपयोगकर्ता कुछ मान, आदानों आदि, जीयूआई में मैं डिस्क पर Output.png के ऊपर लिख और डिस्क से नई छवि के साथ JLabel अपडेट करना पड़ता है बदलता है।।

क्या इसके लिए कोई और सुरुचिपूर्ण/कुशल समाधान है? क्या यह मट ऑब्जेक्ट सीधे कैनवास या छवि या स्विंग में छवि के रूप में प्रिंट करने योग्य कुछ भी है?

उत्तर

9

jpeg एन्कोडिंग दिलचस्प है, लेकिन वहाँ एक जोड़े समस्याएं हैं:

  • यह है नहीं एक दोषरहित प्रारूप, जब
  • यह काफी कुछ समय लगता है (संपीड़ित आप छवि डेटा खो देंगे लगभग 6 से 10 गुना नीचे दिए गए सुझाव से एक) से अधिक समय
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

केवल एक नोट: imencode() फ़ंक्शन में आप ".png" भी सेट कर सकते हैं। यह प्रोग्रामर की ज़रूरतों पर निर्भर करता है, इसलिए मुझे लगता है कि – andriy

+0

जानकारी का कोई नुकसान नहीं है। समस्या यह है कि यह बहुत लंबा लगता है। उपर्युक्त प्रक्रिया सबसे तेज़ संभव है। मेरा मानना ​​है कि केवल मूल स्मृति को इंगित करना तेज होगा। – dannyxyz22

+0

मैंने जो समाधान प्रस्तावित किया है वह जीयूआई को पर्याप्त तेज़ी से लोड करेगा, लेकिन वैसे भी, मैंने आपका जवाब बहुत उपयोगी पाया है। जब मैं ओपनसीवी में और इमेजजे की तुलना में पहली बार प्रोसेसिंग करता हूं और हजारों छवियों के साथ ऐसा करता हूं तो मैं इस तकनीक का उपयोग करता हूं (मफ को बुफर्ड इमेज में बदलता हूं)।और यहां गति वास्तव में मायने रखती है – andriy

14

हां ऐसा करने के लिए और अधिक शानदार तरीका है। आप BufferedImage प्रकार के लिए मैट संगीत कर सकते हैं और फिर इसे स्विंग के साथ लोड करें। यह बफर छवि को बदलने के लिए कोड है:

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(); 
    } 

और फिर आप बस अपने जीयूआई वस्तु में यह पेंट कर सकते हैं:

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

जहां ग्राम प्रकार ग्राफिक्स का

आशा इस मदद करता है।

2

यह एक रेडीमेड है जावा ओपनसीवी में समतुल्य Imshow() के लिए समाधान इसका उपयोग करने में आसान है। एपीआई दिखेगा की तरह:

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

यहाँ https://github.com/master-atul/ImShow-Java-OpenCV

जाएँ यह एक बेहतर समाधान है के रूप में आप डिस्क में छवि को संग्रहीत और नहीं पढ़ते फिर से। इसलिए यह डिस्क से पढ़ने के ऊपरी हिस्से को कम करता है और इस प्रकार तेज़ होता है।

+0

हाय एमएमडी में, मैं विचार पसंद अधिक संक्षिप्त आईएमएसओ कक्षा बनाने के लिए प्रत्येक स्विंग जीयूआई को लपेटने का। मुझे लगता है कि आपको शो इमेज (मैट आईएमजी) विधि में अपने दृष्टिकोण का उपयोग करना चाहिए, क्योंकि यह लगभग 5 गुना तेज है। कक्षा के लिए धन्यवाद =) – dannyxyz22

+0

टिप्पणी के लिए धन्यवाद .. मैं इसे शामिल करूँगा ... – Atul

1

@ एंड्री के anwser का उपयोग कर। मैं इस समाधान के साथ आया था। मैंने ग्राफिक्स के बजाय जेफ्रेम का इस्तेमाल किया। उम्मीद है की यह मदद करेगा।

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(); 
    } 
} 
संबंधित मुद्दे