2016-07-07 529 views
2

我想從一臺PC(客戶端)發送圖像文件到另一臺運行MATLAB的服務器(服務器),輸出圖像空出來。從計算機之間發送圖像,從Java到MATLAB

從不同的討論中,我瞭解到主要問題是Java和MATLAB之間的一些「圖像矩陣不匹配」。但是,我並不完全瞭解這個問題。

如果您能給我一些建議,我將不勝感激。

客戶端的Java代碼:

import java.awt.image.BufferedImage; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.IOException; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 

import javax.imageio.ImageIO; 

public class myclientimage 
{ 
    public static void main(String args[]) throws IOException 
    { 
     BufferedImage img = ImageIO.read(new File("D:\\zzz.jpg")); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream();   
     ImageIO.write(img, "jpg", baos); 
     baos.flush(); 
     byte[] buffer = baos.toByteArray(); 

     DatagramSocket clientSocket = new DatagramSocket();  
     InetAddress IPAddress = InetAddress.getByName("192.168.0.102"); 
     System.out.println(buffer.length); 

     DatagramPacket packet = new DatagramPacket(buffer, buffer.length, IPAddress, 9091); 

     clientSocket.send(packet); 

     System.out.println("aaaa"); 
    } 

} 

服務器的MATLAB代碼:

udpA=udp('192.168.0.104', 9090,'LocalPort', 9091); 
fopen(udpA); 
A = fread(udpA, 200000); 

du = reshape(A,size(A)); % converting vector du to 3d Image array 
imwrite(uint8(du), 'du.jpg'); %save our du to file du.jpg 
I = imread('du.jpg'); %test if it saved correctly 
imshow(I); 

fclose(udpA); 
+0

這是什麼 「不同的討論」?請提供一個鏈接。 –

+0

我沒有特別的鏈接。我從matlab論壇和隨機博客文章閱讀了一些帖子。 – user1850484

+0

A的值是512x1的兩倍。這顯然不足以繪製圖像。實際圖像尺寸爲307x307x3 uint8。我增加了UDP的buffersize和timeout-interval。還是行不通。 – user1850484

回答

5

好了,所以這裏的解決方案。有些東西需要首先澄清,我們將圖像作爲壓縮的jpeg發送,而不是作爲獨立的像素。因此imwrite不能用於此目的,因爲它需要圖像輸入(3D陣列)。那麼你應該使用fwrite來代替。

另一個(次要)問題是,按照您正在操作的方式將BufferedImage讀爲字節會給您不同的大小,我認爲您在打印buffer.length時發現了這一點,並獲得與計算機報告的大小不同的大小。對此的解決方案可以在in the second answer of this question找到。然而,這對圖像沒有影響(可能會降低質量?)傳輸爲我工作,不管鏈接中提到的解決方案。

正如你在評論中已經提到的那樣,你正在接受512雙打。所以基本上有三件事情需要做:

  1. 增加您的UDP對象的InputBufferSize(默認512字節)。
  2. 增加UDP對象的InputDatagramPacketSize(默認值爲8KB),除非您不希望文件大於此大小,否則您將以大塊格式發送文件。
  3. 將雙打轉換爲uint8,因爲這是你如何接收它們。

最終的Java代碼:

public class SendImageUDP { 
    public static void main(String args[]) throws IOException { 
    BufferedImage img = ImageIO.read(new File("your_pic.jpg")); 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ImageIO.write(img, "jpg", baos); 
    baos.flush(); 
    byte[] imageBuffer = baos.toByteArray(); 
    System.out.println(imageBuffer.length); 

    InetAddress IPAddress = InetAddress.getByName("127.0.0.1"); // LocalHost for testing on the same computer 
    DatagramSocket clientSocket = new DatagramSocket(9090, IPAddress); // Specify sending socket 

    DatagramPacket packet = new DatagramPacket(imageBuffer, imageBuffer.length, IPAddress, 9091); 
    clientSocket.send(packet); 

    System.out.println("data sent"); 
    clientSocket.close(); 
    } 
} 

最後的MATLAB代碼:

clear 
close all 

%% Define computer-specific variables 

ipSender = '127.0.0.1'; % LocalHost for testing on the same computer 
portSender = 9090; 

ipReceiver = '127.0.0.1'; % LocalHost for testing on the same computer 
portReceiver = 9091; 

%% Create UDP Object 

udpReceiver = udp(ipSender, portSender, 'LocalPort', portReceiver); 
udpReceiver.InputBufferSize = 102400; % 100KB to be safe 
udpReceiver.InputDatagramPacketSize = 65535; % Max possible 

%% Connect to UDP Object 

fopen(udpReceiver); 
[A, count] = fread(udpReceiver, 102400, 'uint8'); % Receiving in proper format, big size just to be safe 
A = uint8(A); % Just making sure it worked correctly 

fileID = fopen('du.jpg','w'); % Save as a JPEG file because it was received this way 
fwrite(fileID, A); 
I = imread('du.jpg'); % Test if it saved correctly 
imshow(I); 

%% Close 

fclose(udpReceiver); 
delete(udpReceiver); 

你可以從MATLAB代碼中看到的,就沒有必要重塑接收到的數據,因爲它是已經壓縮了JPEG數據,無論如何重塑它都沒有意義。只需將其寫入文件。

來源:

+1

你就像天使一樣!非常感謝你。 – user1850484

+0

哈哈哈:隨時祝你好運! –