介紹:
出于教育目的,我開發了一個Java類,使學生能夠以
Java: 我的基于 Java 的方法最終得到如下影像:

我認為它還不錯,但并不完美。使用其他模型,例如 Google 的imagenet_mobilenet模型,我得到了類似的結果,但我想在 Jupyter 筆記本中運行在線演示時,它們總是會更好一些。我沒有更多的證據——只有一種感覺。在某些情況下,來自在線演示的相同影像被識別為不同的類 - 但并非總是如此。稍后我可能會提供更多相關資料。
假設和作業尚未完成:
我的 Java 代碼中的資料結構或演算法可能存在錯誤。我真的在網上搜索了幾個星期,但我不確定我的代碼是否真的準確,主要是因為那里的例子太少了。例如,我嘗試更改 RGB 的順序或在將影像轉換為 ND 陣列的方法中的計算方式。但是,我沒有看到任何重大變化。也許錯誤在其他任何地方。不過,大概就是這樣吧。如果我的代碼運行良好且正確,那對我來說也可以 - 但我仍然想知道為什么會有差異。感謝您的回答!
代碼:
這是一個包含兩個類的完整作業示例(我知道,帶有面板繪圖的框架很糟糕 - 我為這個示例快速撰寫了這個代碼)
/**
* 1. TensorFlow Core API Library: org.tensorflow -> tensorflow-core-api
* https://mvnrepository.com/artifact/org.tensorflow/tensorflow-core-api
* -> tensorflow-core-api-0.4.0.jar
*
* 2. additionally click "View All" and open:
* https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.4.0/
* Download the correct native library for your OS
* -> tensorflow-core-api-0.4.0-macosx-x86_64.jar
* -> tensorflow-core-api-0.4.0-windows-x86_64.jar
* -> tensorflow-core-api-0.4.0-linux-x86_64.jar
*
* 3. TensorFlow Framework Library: org.tensorflow -> tensorflow-framework
* https://mvnrepository.com/artifact/org.tensorflow/tensorflow-framework/0.4.0
* -> tensorflow-framework-0.4.0.jar
*
* 4. Protocol Buffers [Core]: com.google.protobuf -> protobuf-java
* https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java
* -> protobuf-java-4.0.0-rc-2.jar
*
* 5. JavaCPP: org.bytedeco -> javacpp
* https://mvnrepository.com/artifact/org.bytedeco/javacpp
* -> javacpp-1.5.7.jar
*
* 6. TensorFlow NdArray Library: org.tensorflow -> ndarray
* https://mvnrepository.com/artifact/org.tensorflow/ndarray
* -> ndarray-0.3.3.jar
*/
import org.tensorflow.SavedModelBundle;
import org.tensorflow.Tensor;
import org.tensorflow.ndarray.IntNdArray;
import org.tensorflow.ndarray.NdArrays;
import org.tensorflow.ndarray.Shape;
import org.tensorflow.types.TInt32;
import java.util.HashMap;
import java.util.Map;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.BorderLayout;
public class MoveNetDemo {
private SavedModelBundle model;
private String inputLayerName;
private String outputLayerName;
private String keyName;
private BufferedImage image;
private float[][] output;
private int width;
private int height;
public MoveNetDemo(String pFoldername, int pImageWidth, int pImageHeight) {
width = pImageWidth;
height = pImageHeight;
model = SavedModelBundle.load(pFoldername, "serve");
// Read input and output layer names from file
inputLayerName = model.signatures().get(0).getInputs().keySet().toString();
outputLayerName = model.signatures().get(0).getOutputs().keySet().toString();
inputLayerName = inputLayerName.substring(1, inputLayerName.length()-1);
outputLayerName = outputLayerName.substring(1, outputLayerName.length()-1);
keyName = model.signatures().get(0).key();
}
// not necessary here
public String getModelInformation() {
String infos = "";
for (int i=0; i<model.signatures().size(); i ) {
infos = model.signatures().get(i).toString();
}
return infos;
}
public void setData(String pFilename) {
image = null;
try {
image = ImageIO.read(new File(pFilename));
}
catch (Exception e) {
}
}
public BufferedImage getData() {
return image;
}
private IntNdArray fillIntNdArray(IntNdArray pMatrix, BufferedImage pImage) {
try {
int w = pImage.getWidth();
int h = pImage.getHeight();
for (int i = 0; i < h; i ) {
for (int j = 0; j < w; j ) {
Color mycolor = new Color(pImage.getRGB(j, i));
int red = mycolor.getRed();
int green = mycolor.getGreen();
int blue = mycolor.getBlue();
pMatrix.setInt(red, 0, j, i, 0);
pMatrix.setInt(green, 0, j, i, 1);
pMatrix.setInt(blue, 0, j, i, 2);
}
}
}
catch (Exception e) {
}
return pMatrix;
}
public void run() {
Map<String, Tensor> feed_dict = null;
IntNdArray input_matrix = NdArrays.ofInts(Shape.of(1, width, height, 3));
input_matrix = fillIntNdArray(input_matrix, image);
Tensor input_tensor = TInt32.tensorOf(input_matrix);
feed_dict = new HashMap<>();
feed_dict.put(inputLayerName, input_tensor);
Map<String, Tensor> res = model.function(keyName).call(feed_dict);
Tensor output_tensor = res.get(outputLayerName);
output = new float[17][3];
for (int i= 0; i<17; i ) {
output[i][0] = output_tensor.asRawTensor().data().asFloats().getFloat(i*3)*256;
output[i][1] = output_tensor.asRawTensor().data().asFloats().getFloat(i*3 1)*256;
output[i][2] = output_tensor.asRawTensor().data().asFloats().getFloat(i*3 2);
}
}
public float[][] getOutputArray() {
return output;
}
public static void main(String[] args) {
MoveNetDemo im = new MoveNetDemo("/Users/myname/Downloads/Code/TF_Test_04_NEW/movenet_singlepose_thunder_4", 256, 256);
im.setData("/Users/myname/Downloads/Code/TF_Test_04_NEW/test.jpeg");
JFrame jf = new JFrame("TEST");
jf.setSize(300, 300);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImagePanel ip = new ImagePanel(im.getData());
jf.add(ip, BorderLayout.CENTER);
JButton st = new JButton("RUN");
st.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
im.run();
ip.update(im.getOutputArray());
}
});
jf.add(st, BorderLayout.NORTH);
jf.setVisible(true);
}
}
和 ImagePanel 類:
import javax.swing.JPanel;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.Color;
public class ImagePanel extends JPanel {
private BufferedImage image;
private float[][] points;
public ImagePanel(BufferedImage pImage) {
image = pImage;
}
public void update(float[][] pPoints) {
points = pPoints;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0,0,null);
g.setColor(Color.GREEN);
if (points != null) {
for (int j=0; j<17; j ) {
g.fillOval((int)points[j][0], (int)points[j][1], 5, 5);
}
}
}
}
uj5u.com熱心網友回復:
我找到了答案。我把高度和寬度混合了兩次!不知道,為什么它的行為如此奇怪(幾乎正確但不完美)但它現在可以作業了。
在 Jupyter 筆記本中它說:
input_image: A [1, height, width, 3]
所以我將方法 fillIntArray 更改為:
private IntNdArray fillIntNdArray(IntNdArray pMatrix, BufferedImage pImage) {
try {
int w = pImage.getWidth();
int h = pImage.getHeight();
for (int i = 0; i < h; i ) {
for (int j = 0; j < w; j ) {
Color mycolor = new Color(pImage.getRGB(j, i));
int red = mycolor.getRed();
int green = mycolor.getGreen();
int blue = mycolor.getBlue();
pMatrix.setInt(red, 0, i, j, 0); // switched j and i
pMatrix.setInt(green, 0, i, j, 1); // switched j and i
pMatrix.setInt(blue, 0, i, j, 2); // switched j and i
}
}
}
catch (Exception e) {
}
return pMatrix;
}
并相應地在 run() 方法中:
IntNdArray input_matrix = NdArrays.ofInts(Shape.of(1, height, width, 3));
在 Jupyter 筆記本中,您可以切換輔助函式以進行可視化,并看到首先獲取 y 坐標,然后獲取 x 坐標。先高,后寬。在 ImagePanel 類中也進行更改,解決了問題,分類與預期的一樣,與在線演示中的質量相同!
if (points != null) {
for (int j=0; j<17; j ) {
// switched 0 and 1
g.fillOval((int)points[j][1], (int)points[j][0], 5, 5);
}
}
這里是:

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/467558.html
