2017-12-26 29 views
6

Tensorflow 제공된 그림에서 객체를 인식하기 위해 tutorial 다음에 this repo을 사용하여 그림에서 객체를 반환하는 데 성공했습니다. 예를 들어 이 내가 입력으로 사용되는 사진입니다 :그림 안에서 인식 된 물체의 색상을 얻을 수있는 방법이 있습니까?

red-tshirt.jpg

은 여기 내 프로그램의 출력입니다 :

enter image description here

내가 원하는 모든 인식 된 항목의 색상을 얻을 수 있습니다 (마지막 사건에 대한 빨간 저지), 그게 가능하니? 여기

은 '당신은 당신이 돈 그래서 즉, 약간의 훈련을받은 클래스에서 이미지를 분류, 지정된 이미지의 레이블을 예측하는 코드를 사용하는 (단지 작은 변화와 마지막 링크에서) 코드

/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. 
Licensed under the Apache License, Version 2.0 (the "License"); 
you may not use this file except in compliance with the License. 
You may obtain a copy of the License at 
    http://www.apache.org/licenses/LICENSE-2.0 
Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
See the License for the specific language governing permissions and 
limitations under the License. 
==============================================================================*/ 

package com.test.sec.compoment; 

import java.io.IOException; 
import java.io.PrintStream; 
import java.nio.charset.Charset; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.util.Arrays; 
import java.util.List; 
import org.tensorflow.DataType; 
import org.tensorflow.Graph; 
import org.tensorflow.Output; 
import org.tensorflow.Session; 
import org.tensorflow.Tensor; 
import org.tensorflow.TensorFlow; 
import org.tensorflow.types.UInt8; 

/** Sample use of the TensorFlow Java API to label images using a pre-trained model. */ 
public class ImageRecognition { 
    private static void printUsage(PrintStream s) { 
    final String url = 
     "https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip"; 
    s.println(
     "Java program that uses a pre-trained Inception model (http://arxiv.org/abs/1512.00567)"); 
    s.println("to label JPEG images."); 
    s.println("TensorFlow version: " + TensorFlow.version()); 
    s.println(); 
    s.println("Usage: label_image <model dir> <image file>"); 
    s.println(); 
    s.println("Where:"); 
    s.println("<model dir> is a directory containing the unzipped contents of the inception model"); 
    s.println("   (from " + url + ")"); 
    s.println("<image file> is the path to a JPEG image file"); 
    } 

    public void index() { 
     String modelDir = "C:/Users/Admin/Downloads/inception5h"; 
     String imageFile = "C:/Users/Admin/Desktop/red-tshirt.jpg"; 

    byte[] graphDef = readAllBytesOrExit(Paths.get(modelDir, "tensorflow_inception_graph.pb")); 
    List<String> labels = 
     readAllLinesOrExit(Paths.get(modelDir, "imagenet_comp_graph_label_strings.txt")); 
    byte[] imageBytes = readAllBytesOrExit(Paths.get(imageFile)); 

    try (Tensor<Float> image = constructAndExecuteGraphToNormalizeImage(imageBytes)) { 
     float[] labelProbabilities = executeInceptionGraph(graphDef, image); 
     int bestLabelIdx = maxIndex(labelProbabilities); 
     System.out.println(
      String.format("BEST MATCH: %s (%.2f%% likely)", 
       labels.get(bestLabelIdx), 
       labelProbabilities[bestLabelIdx] * 100f)); 
    } 
    } 

    private static Tensor<Float> constructAndExecuteGraphToNormalizeImage(byte[] imageBytes) { 
    try (Graph g = new Graph()) { 
     GraphBuilder b = new GraphBuilder(g); 
     // Some constants specific to the pre-trained model at: 
     // https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip 
     // 
     // - The model was trained with images scaled to 224x224 pixels. 
     // - The colors, represented as R, G, B in 1-byte each were converted to 
     // float using (value - Mean)/Scale. 
     final int H = 224; 
     final int W = 224; 
     final float mean = 117f; 
     final float scale = 1f; 

     // Since the graph is being constructed once per execution here, we can use a constant for the 
     // input image. If the graph were to be re-used for multiple input images, a placeholder would 
     // have been more appropriate. 
     final Output<String> input = b.constant("input", imageBytes); 
     final Output<Float> output = 
      b.div(
       b.sub(
        b.resizeBilinear(
         b.expandDims(
          b.cast(b.decodeJpeg(input, 3), Float.class), 
          b.constant("make_batch", 0)), 
         b.constant("size", new int[] {H, W})), 
        b.constant("mean", mean)), 
       b.constant("scale", scale)); 
     try (Session s = new Session(g)) { 
     return s.runner().fetch(output.op().name()).run().get(0).expect(Float.class); 
     } 
    } 
    } 

    private static float[] executeInceptionGraph(byte[] graphDef, Tensor<Float> image) { 
    try (Graph g = new Graph()) { 
     g.importGraphDef(graphDef); 
     try (Session s = new Session(g); 
      Tensor<Float> result = 
       s.runner().feed("input", image).fetch("output").run().get(0).expect(Float.class)) { 
     final long[] rshape = result.shape(); 
     if (result.numDimensions() != 2 || rshape[0] != 1) { 
      throw new RuntimeException(
       String.format(
        "Expected model to produce a [1 N] shaped tensor where N is the number of labels, instead it produced one with shape %s", 
        Arrays.toString(rshape))); 
     } 
     int nlabels = (int) rshape[1]; 
     return result.copyTo(new float[1][nlabels])[0]; 
     } 
    } 
    } 

    private static int maxIndex(float[] probabilities) { 
    int best = 0; 
    for (int i = 1; i < probabilities.length; ++i) { 
     if (probabilities[i] > probabilities[best]) { 
     best = i; 
     } 
    } 
    return best; 
    } 

    private static byte[] readAllBytesOrExit(Path path) { 
    try { 
     return Files.readAllBytes(path); 
    } catch (IOException e) { 
     System.err.println("Failed to read [" + path + "]: " + e.getMessage()); 
     System.exit(1); 
    } 
    return null; 
    } 

    private static List<String> readAllLinesOrExit(Path path) { 
    try { 
     return Files.readAllLines(path, Charset.forName("UTF-8")); 
    } catch (IOException e) { 
     System.err.println("Failed to read [" + path + "]: " + e.getMessage()); 
     System.exit(0); 
    } 
    return null; 
    } 

    // In the fullness of time, equivalents of the methods of this class should be auto-generated from 
    // the OpDefs linked into libtensorflow_jni.so. That would match what is done in other languages 
    // like Python, C++ and Go. 
    static class GraphBuilder { 
    GraphBuilder(Graph g) { 
     this.g = g; 
    } 

    Output<Float> div(Output<Float> x, Output<Float> y) { 
     return binaryOp("Div", x, y); 
    } 

    <T> Output<T> sub(Output<T> x, Output<T> y) { 
     return binaryOp("Sub", x, y); 
    } 

    <T> Output<Float> resizeBilinear(Output<T> images, Output<Integer> size) { 
     return binaryOp3("ResizeBilinear", images, size); 
    } 

    <T> Output<T> expandDims(Output<T> input, Output<Integer> dim) { 
     return binaryOp3("ExpandDims", input, dim); 
    } 

    <T, U> Output<U> cast(Output<T> value, Class<U> type) { 
     DataType dtype = DataType.fromClass(type); 
     return g.opBuilder("Cast", "Cast") 
      .addInput(value) 
      .setAttr("DstT", dtype) 
      .build() 
      .<U>output(0); 
    } 

    Output<UInt8> decodeJpeg(Output<String> contents, long channels) { 
     return g.opBuilder("DecodeJpeg", "DecodeJpeg") 
      .addInput(contents) 
      .setAttr("channels", channels) 
      .build() 
      .<UInt8>output(0); 
    } 

    <T> Output<T> constant(String name, Object value, Class<T> type) { 
     try (Tensor<T> t = Tensor.<T>create(value, type)) { 
     return g.opBuilder("Const", name) 
      .setAttr("dtype", DataType.fromClass(type)) 
      .setAttr("value", t) 
      .build() 
      .<T>output(0); 
     } 
    } 
    Output<String> constant(String name, byte[] value) { 
     return this.constant(name, value, String.class); 
    } 

    Output<Integer> constant(String name, int value) { 
     return this.constant(name, value, Integer.class); 
    } 

    Output<Integer> constant(String name, int[] value) { 
     return this.constant(name, value, Integer.class); 
    } 

    Output<Float> constant(String name, float value) { 
     return this.constant(name, value, Float.class); 
    } 

    private <T> Output<T> binaryOp(String type, Output<T> in1, Output<T> in2) { 
     return g.opBuilder(type, type).addInput(in1).addInput(in2).build().<T>output(0); 
    } 

    private <T, U, V> Output<T> binaryOp3(String type, Output<U> in1, Output<V> in2) { 
     return g.opBuilder(type, type).addInput(in1).addInput(in2).build().<T>output(0); 
    } 
    private Graph g; 
    } 
} 
+0

이 프로그램은 당신이 그것을 밖으로 분할을 얻으려면 완전히 길쌈 네트워크를 사용하는 데 필요한 개시 네트워크 https://arxiv.org/pdf/1512.00567v2.pdf을 사용하고 있습니다. – matt

+0

@matt 여기에서 분실했습니다 –

+0

이 네트워크는 세그먼트 화를 생성하지 않습니다. 그것은 단지 이미지를 분류합니다. 저지 모양이나 픽셀을 추출하지 않습니다. 따라서 기존 코드를 사용하려면 이미지의 히스토그램을 가져 와서 가장 일반적인 색상을 잡는 것이 좋습니다. – matt

답변

6

입니다 당신의 물체의 정확한 픽셀을 안다.

그래서, 나는

  1. 객체의 위치를 ​​감지하고 경계 상자를 얻기 위해 object detector를 사용하여, 당신은 다음 중 하나를 수행하는 것이 좋습니다. 그런 다음 가장 많은 픽셀의 색상을 가져옵니다.
  2. this과 같은 픽셀 단위 분류 (세분화)를 사용하면 개체의 정확한 픽셀을 얻을 수 있습니다.

주, 당신은 수동으로 개체에 대한 네트워크 (모델)을 훈련해야 할 수 있습니다

편집 :

자바 물체 감지 예를 들어

android에 대한 코딩 this 프로젝트를 보라 데스크톱 응용 프로그램에서 사용하는 것은 간단해야합니다. 더 구체적으로 this 부분을 살펴보십시오.

동시에 개체 검색과 세분화가 필요하지 않지만 원한다면 먼저 파이썬 (링크가 위에서 제공됨)을 사용하여 세분화 모델을 교육하고 다음과 같이 Java에서 모델을 사용하십시오. 객체 검출 모델

편집 2 :

나는 당신이 자바의 모든 냉동 모델을 사용할 수 있음을 보여주기 위해 단지 Tensorflow 개체 탐지 API models를 사용 javasimple object detection client을 추가했습니다.

또한 픽셀 단위로 세분화 된이 아름다운 repository을 확인하십시오.

enter image description here

+0

이것은 파이썬에서만 가능합니다. –

+0

'tensorflow' 객체 감지 기능을 Java에서도 사용할 수 있습니다 – Ultraviolet

+0

세그먼트 화와 객체 감지 모두에 대한 링크를 제공 할 수 있습니까? –

0

를 사용하여 RGB 색상 코드를 제공하는 아래의 코드는, 수도 (예 : 가운데)를 결정하고 세로 (Y) 및 가로 (X) 좌표가있는 RGB 코드를 가져와야합니다.

//create image object from byte array 
BufferedImage imageobj=null; 
Color[][] imgcolor=null; 
try { 
    imageobj=ImageIO.read(new ByteArrayInputStream(imageBytes)); 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
if(imageobj!=null){ 
    imgcolor=new Color[imageobj.getWidth()][imageobj.getHeight()]; 
    for(int i=0;i<imageobj.getWidth();i++){ 
     for(int j=0;j<imageobj.getHeight();j++){ 
      imgcolor[i][j]=new Color(imageobj.getRGB(i, j)); 
     } 
    } 
} 


if(imgcolor!=null && imgcolor.length>0){ 
      System.out.println("Object Color "+imgcolor[imageobj.getWidth()/2][imageobj.getHeight()/2].toString()); 
     } 
+0

개체가 가운데에있는 경우에만 유효합니다. –