Skip to content

Instantly share code, notes, and snippets.

@YSRKEN
Last active October 19, 2015 02:13
Show Gist options
  • Save YSRKEN/9b25897c2a815fd0cd22 to your computer and use it in GitHub Desktop.
Save YSRKEN/9b25897c2a815fd0cd22 to your computer and use it in GitHub Desktop.
やさしい画像認識教室~ゲーム編~ ref: http://qiita.com/YSRKEN/items/819dd3acf750ff5c0e7f
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class sample1 extends JPanel{
static BufferedImage image;
// main関数
public static void main(String args[]){
if(args.length < 1) return;
try{
// 画像を読み込む
image = ImageIO.read(new File(args[0]));
// フレームを作成して表示する
JFrame frame = new JFrame("テスト");
sample1 panel = new sample1();
frame.getContentPane().add(panel);
frame.getContentPane().setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
// 画像を読み取って情報を表示する
JOptionPane.showMessageDialog(frame, getInfo(image));
}
catch(IOException error){
error.printStackTrace();
}
}
// 画像を読み取って情報を表示する
private static String getInfo(BufferedImage image){
String info = "";
/* 認識処理 */
return info;
}
// 画面を描画する
public void paintComponent(Graphics graphics){
graphics.drawImage(image, 0, 0, this);
}
}
static final int cc_threshold = 500; //カラーピックした際のしきい値(経験上決めた)
// カラーピックして指定色と十分に近いと言えるかを判定する
private static boolean checkColor(int x, int y, int color){
int argb = image.getRGB(x, y);
int r_diff = ((argb & 0xFF0000) >> 16) - ((color & 0xFF0000) >> 16);
int g_diff = ((argb & 0xFF00) >> 8) - ((color & 0xFF00) >> 8);
int b_diff = (argb & 0xFF) - (color & 0xFF);
int diff = r_diff * r_diff + g_diff * g_diff + b_diff * b_diff;
if(diff < cc_threshold) return true; else return false;
}
// 画像を読み取って情報を表示する
private static String getInfo(){
String info = "";
/* 認識処理 */
// 艦船数
int[] fleet = {1, 1};
for(int k = 5; k > 0; k--){
if(checkColor(33, 119 + 45 * k, 0x747572)){
fleet[0] = k + 1;
break;
}
}
for(int k = 5; k > 0; k--){
if(checkColor(686, 188 + 45 * k, 0x747572)){
fleet[1] = k + 1;
break;
}
}
info += "艦船数:" + fleet[0] + "/" + fleet[1] + "\n";
return info;
}
static final double name_threshold = 127.5; //艦名判定の際のしきい値
static HashMap<Long, String> map = new HashMap<Long,String>(); //艦名検索
// 艦名データを初期化する
map.put(0x000ffffffcL, "暁"); //通常
map.put(0x7ffe7fffffL, "響"); //通常
map.put(0x003fffffffL, "雷"); //通常
map.put(0x00dffffffeL, "雷"); //中破
map.put(0x088be7ffffL, "電"); //通常
map.put(0x80e0000003L, "駆逐イ級");
map.put(0x9be7c00000L, "駆逐ロ級");
private static String getInfo(){
(中略)
// 艦名
info += "自艦隊:";
for(int k = 0; k < fleet[0]; k++){
// 40ビットの入力データを取得する
long unit_data = 0;
for(int m = 0; m < 40; m++){
// Yの値を取得する
int argb = image.getRGB(97, m + 78 + 45 * k);
int r = ((argb & 0xFF0000) >> 16);
int g = ((argb & 0xFF00) >> 8);
int b = (argb & 0xFF);
double y = 0.299 * r + 0.587 * g + 0.114 * b;
// しきい値で判断して、unit_dataに加算する
unit_data <<= 1;
if(y >= name_threshold)unit_data += 1;
}
if(k != 0)info += "/";
if(map.containsKey(unit_data)){
info += map.get(unit_data);
}else{
info += "不明";
}
}
info += "\n敵艦隊:";
for(int k = 0; k < fleet[1]; k++){
// 40ビットの入力データを取得する
long unit_data = 0;
for(int m = 0; m < 40; m++){
// Yの値を取得する
int argb = image.getRGB(739, m + 147 + 45 * k);
int r = ((argb & 0xFF0000) >> 16);
int g = ((argb & 0xFF00) >> 8);
int b = (argb & 0xFF);
double y = 0.299 * r + 0.587 * g + 0.114 * b;
// しきい値で判断して、unit_dataに加算する
unit_data <<= 1;
if(y >= name_threshold)unit_data += 1;
}
if(k != 0)info += "/";
if(map.containsKey(unit_data)){
info += map.get(unit_data);
}else{
info += "不明";
}
}
info += "\n";
}
static HashMap<Integer, String> damage_map = new HashMap<Integer,String>(); //損害判定
// 損害判定を初期化する
damage_map.put(0xe3d052, "小破");
damage_map.put(0xc9944a, "中破");
damage_map.put(0x6d2e27, "大破");
damage_map.put(0x4b9fd4, "撃沈");
private static String getInfo(){
(中略)
// 損害判定
info += "損害判定:";
for(int k = 0; k < fleet[0]; k++){
if(k != 0)info += ".";
boolean flg = false;
for(HashMap.Entry<Integer, String> entry : damage_map.entrySet()){
if(checkColor(140, 105 + 45 * k, entry.getKey())){
info += entry.getValue();
flg = true;
break;
}
}
if(!flg){
if(checkColor(163, 79 + 45 * k, 0x19FD19)){
info += "無傷";
}else{
info += "軽微";
}
}
}
info += " / ";
for(int k = 0; k < fleet[1]; k++){
if(k != 0)info += ".";
boolean flg = false;
for(HashMap.Entry<Integer, String> entry : damage_map.entrySet()){
if(checkColor(780, 174 + 45 * k, entry.getKey())){
info += entry.getValue();
flg = true;
break;
}
}
if(!flg){
if(checkColor(636, 148 + 45 * k, 0x19FD19)){
info += "無傷";
}else{
info += "軽微";
}
}
}
}
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class sample1 extends JPanel{
static final int cc_threshold = 500; //カラーピックした際のしきい値(経験上決めた)
static final double name_threshold = 127.5; //艦名判定の際のしきい値
static BufferedImage image; //読み込んだ画像
static HashMap<Long, String> unit_map = new HashMap<Long,String>(); //艦名検索
static HashMap<Integer, String> damage_map = new HashMap<Integer,String>(); //損害判定
// main関数
public static void main(String args[]){
if(args.length < 1) return;
try{
// 画像を読み込む
image = ImageIO.read(new File(args[0]));
// フレームを作成して表示する
JFrame frame = new JFrame("テスト");
sample1 panel = new sample1();
frame.getContentPane().add(panel);
frame.getContentPane().setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
// 艦名データを初期化する
unit_map.put(0x000ffffffcL, "暁"); //通常
unit_map.put(0x7ffe7fffffL, "響"); //通常
unit_map.put(0x003fffffffL, "雷"); //通常
unit_map.put(0x00dffffffeL, "雷"); //中破
unit_map.put(0x088be7ffffL, "電"); //通常
unit_map.put(0x83c000000cL, "駆逐イ級");
unit_map.put(0x9d81e00000L, "駆逐ロ級");
// 損害判定を初期化する
damage_map.put(0xe3d052, "小破");
damage_map.put(0xc9944a, "中破");
damage_map.put(0x6d2e27, "大破");
damage_map.put(0x4b9fd4, "撃沈");
// 画像を読み取って情報を表示する
JOptionPane.showMessageDialog(frame, getInfo());
}
catch(IOException error){
error.printStackTrace();
}
}
// カラーピックして指定色と十分に近いと言えるかを判定する
private static boolean checkColor(int x, int y, int color){
int argb = image.getRGB(x, y);
int r_diff = ((argb & 0xFF0000) >> 16) - ((color & 0xFF0000) >> 16);
int g_diff = ((argb & 0xFF00) >> 8) - ((color & 0xFF00) >> 8);
int b_diff = (argb & 0xFF) - (color & 0xFF);
int diff = r_diff * r_diff + g_diff * g_diff + b_diff * b_diff;
if(diff < cc_threshold) return true; else return false;
}
// 画像を読み取って情報を表示する
private static String getInfo(){
long start = System.nanoTime();
String info = "";
/* 認識処理 */
// 艦船数
int[] fleet = {1, 1};
for(int k = 5; k > 0; k--){
if(checkColor(33, 119 + 45 * k, 0x747572)){
fleet[0] = k + 1;
break;
}
}
for(int k = 5; k > 0; k--){
if(checkColor(686, 188 + 45 * k, 0x747572)){
fleet[1] = k + 1;
break;
}
}
info += "艦船数:" + fleet[0] + "/" + fleet[1] + "\n";
// 艦名
info += "自艦隊:";
for(int k = 0; k < fleet[0]; k++){
// 40ビットの入力データを取得する
long unit_data = 0;
for(int m = 0; m < 40; m++){
// Yの値を取得する
int argb = image.getRGB(97, m + 78 + 45 * k);
int r = ((argb & 0xFF0000) >> 16);
int g = ((argb & 0xFF00) >> 8);
int b = (argb & 0xFF);
double y = 0.299 * r + 0.587 * g + 0.114 * b;
// しきい値で判断して、unit_dataに加算する
unit_data <<= 1;
if(y >= name_threshold)unit_data += 1;
}
if(k != 0)info += "/";
if(unit_map.containsKey(unit_data)){
info += unit_map.get(unit_data);
}else{
info += "不明";
}
}
info += "\n敵艦隊:";
for(int k = 0; k < fleet[1]; k++){
// 40ビットの入力データを取得する
long unit_data = 0;
for(int m = 0; m < 40; m++){
// Yの値を取得する
int argb = image.getRGB(737, m + 147 + 45 * k);
int r = ((argb & 0xFF0000) >> 16);
int g = ((argb & 0xFF00) >> 8);
int b = (argb & 0xFF);
double y = 0.299 * r + 0.587 * g + 0.114 * b;
// しきい値で判断して、unit_dataに加算する
unit_data <<= 1;
if(y >= name_threshold)unit_data += 1;
}
if(k != 0)info += "/";
if(unit_map.containsKey(unit_data)){
info += unit_map.get(unit_data);
}else{
info += "不明";
}
}
info += "\n";
// 損害判定
info += "損害判定:";
for(int k = 0; k < fleet[0]; k++){
if(k != 0)info += ".";
boolean flg = false;
for(HashMap.Entry<Integer, String> entry : damage_map.entrySet()){
if(checkColor(140, 105 + 45 * k, entry.getKey())){
info += entry.getValue();
flg = true;
break;
}
}
if(!flg){
if(checkColor(163, 79 + 45 * k, 0x19FD19)){
info += "無傷";
}else{
info += "軽微";
}
}
}
info += " / ";
for(int k = 0; k < fleet[1]; k++){
if(k != 0)info += ".";
boolean flg = false;
for(HashMap.Entry<Integer, String> entry : damage_map.entrySet()){
if(checkColor(780, 174 + 45 * k, entry.getKey())){
info += entry.getValue();
flg = true;
break;
}
}
if(!flg){
if(checkColor(636, 148 + 45 * k, 0x19FD19)){
info += "無傷";
}else{
info += "軽微";
}
}
}
long stop = System.nanoTime();
System.out.println(stop - start);
return info;
}
// 画面を描画する
public void paintComponent(Graphics graphics){
graphics.drawImage(image, 0, 0, this);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment