Fix graphics recognition algorithms and added a test suite.

secondmonitor
sigonasr2 4 years ago
parent a6958f1669
commit 289cb13833
  1. 2
      DivaBot/colorData
  2. 191
      DivaBot/src/MyRobot.java
  3. 86
      DivaBot/src/TypeFace.java
  4. 39
      DivaBot/src/sig/utils/ImageUtils.java
  5. BIN
      DivaBot/testsuite/shake it!_EXplay_568_88_8_4_7_96.03.png
  6. BIN
      DivaBot/testsuite/え?あぁ、そう。_EXEXplay_499_121_11_9_43_77.11.png
  7. BIN
      DivaBot/testsuite/どういうことなの!?_EXplay_449_85_3_0_3_95.01.png
  8. BIN
      DivaBot/testsuite/サマーアイドル_EXplay_959_56_19_5_10_81.32.png
  9. BIN
      DivaBot/testsuite/テレカクシ思春期_EXplay_44_108_7_4_18_81.8.png
  10. BIN
      DivaBot/testsuite/天樂_EXplay_361_58_9_4_11_92.67.png
  11. BIN
      DivaBot/testsuite/番凩_EXEXplay_41_110_1_10_21_77.76.png
  12. BIN
      DivaBot/testsuite/結ンデ開イテ羅刹ト骸_EXEXplay_47_123_10_5_46_74.19.png
  13. BIN
      DivaBot/typeface1.png
  14. BIN
      DivaBot/typeface2.png

File diff suppressed because one or more lines are too long

@ -1,8 +1,12 @@
import java.awt.Color; import java.awt.Color;
import java.awt.GraphicsDevice; import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Robot; import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.KeyListener; import java.awt.event.KeyListener;
@ -13,6 +17,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Dictionary;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Timer; import java.util.Timer;
@ -31,14 +36,14 @@ import javax.swing.JTextField;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import sig.utils.FileUtils; import sig.utils.FileUtils;
import sig.utils.ImageUtils;
import sig.utils.SoundUtils; import sig.utils.SoundUtils;
public class MyRobot{ public class MyRobot{
Robot MYROBOT; Robot MYROBOT;
Color SCREEN[][]; Color SCREEN[][];
static SongData SONGS[]; static SongData SONGS[];
static String SONGNAMES[] = new String[] {"Yellow","The secret garden","Tell Your World","愛言葉","Weekender Girl","歌に形はないけれど","えれくとりっく・えんじぇぅ","神曲","カンタレラ","巨大少女","クローバー♣クラブ","恋スルVOC@LOID","桜ノ雨 ","39","深海シティアンダーグラウンド","深海少女","積乱雲グラフィティ","千年の独奏歌","ダブルラリアット","ハジメテノオト","初めての恋が終わる時","Packaged","Palette","Freely Tomorrow","from Y to Y","みくみくにしてあげる♪","メルト","モノクロ∞ブルースカイ","ゆめゆめ","1/6 -out of the gravity-","ACUTE","インタビュア","LOL -lots of laugh-","Glory 3usi9","soundless voice","ジェミニ","白い雪のプリンセスは","スキキライ","タイムマシン","Dear","DECORATOR","トリコロール・エア・ライン","Nostalgic","Hand in Hand","Fire◎Flower","ブラック★ロックシューター","メテオ","ワールドイズマイン","アマツキツネ","erase or zero","エレクトロサチュレイタ","on the rocks","からくりピエロ","カラフル×メロディ","Catch the Wave","キャットフード","サマーアイドル","shake it!","Just Be Friends","スイートマジック","SPiCa -39's Giving Day Edition-","番凩","テレカクシ思春期","天樂","どういうことなの!?","東京テディベア","どりーみんチュチュ","トリノコシティ","ネトゲ廃人シュプレヒコール","No Logic","ハイハハイニ","はじめまして地球人さん","*ハロー、プラネット。","Hello, Worker","忘却心中","magnet","右肩の蝶","結ンデ開イテ羅刹ト骸","メランコリック","リモコン","ルカルカ★ナイトフィーバー","炉心融解","WORLD'S END UMBRELLA","アカツキアライヴァル","アゲアゲアゲイン","1925","え?あぁ、そう。","エイリアンエイリアン","ODDS&ENDS","君の体温","こっち向いて Baby","壊セ壊セ","39みゅーじっく!","サンドリヨン","SING&SMILE","スノーマン","DYE","なりすましゲンガー","ヒバナ","ヒビカセ","ブラックゴールド","ミラクルペイント","指切り","ありふれたせかいせいふく","アンハッピーリフレイン","大江戸ジュリアナイト","ゴーストルール","こちら、幸福安心委員会です。","孤独の果て -extend edition-","ジターバグ","Sweet Devil","砂の惑星","テオ","初音ミクの消失","秘密警察","妄想スケッチ","リンちゃんなう!","ローリンガール","ロキ","ロミオとシンデレラ","エンヴィキャットウォーク","骸骨楽団とリリア","サイハテ","ジグソーパズル","千本桜","ピアノ×フォルテ×スキャンダル","Blackjack","ぽっぴっぽー","裏表ラバーズ","Sadistic.Music∞Factory","デンパラダイム","二次元ドリームフィーバー","ネガポジ*コンティニューズ","初音ミクの激唱","ワールズエンド・ダンスホール","ココロ","システマティック・ラヴ","Knife","二息歩行","PIANO*GIRL","夢喰い白黒バク"}; static String SONGNAMES[] = new String[] {"Yellow","The secret garden","Tell Your World","愛言葉","Weekender Girl","歌に形はないけれど","えれくとりっく・えんじぇぅ","神曲","カンタレラ","巨大少女","クローバー♣クラブ","恋スルVOC@LOID","桜ノ雨 ","39","深海シティアンダーグラウンド","深海少女","積乱雲グラフィティ","千年の独奏歌","ダブルラリアット","ハジメテノオト","初めての恋が終わる時","Packaged","Palette","Freely Tomorrow","from Y to Y","みくみくにしてあげる♪","メルト","モノクロ∞ブルースカイ","ゆめゆめ","1/6 -out of the gravity-","ACUTE","インタビュア","LOL -lots of laugh-","Glory 3usi9","soundless voice","ジェミニ","白い雪のプリンセスは","スキキライ","タイムマシン","Dear","DECORATOR","トリコロール・エア・ライン","Nostalgic","Hand in Hand","Fire◎Flower","ブラック★ロックシューター","メテオ","ワールドイズマイン","アマツキツネ","erase or zero","エレクトロサチュレイタ","on the rocks","からくりピエロ","カラフル×メロディ","Catch the Wave","キャットフード","サマーアイドル","shake it!","Just Be Friends","スイートマジック","SPiCa -39's Giving Day Edition-","番凩","テレカクシ思春期","天樂","どういうことなの!?","東京テディベア","どりーみんチュチュ","トリノコシティ","ネトゲ廃人シュプレヒコール","No Logic","ハイハハイニ","はじめまして地球人さん","*ハロー、プラネット。","Hello, Worker","忘却心中","magnet","右肩の蝶","結ンデ開イテ羅刹ト骸","メランコリック","リモコン","ルカルカ★ナイトフィーバー","炉心融解","WORLD'S END UMBRELLA","アカツキアライヴァル","アゲアゲアゲイン","1925","え?あぁ、そう。","エイリアンエイリアン","ODDS&ENDS","君の体温","こっち向いて Baby","壊セ壊セ","39みゅーじっく!","サンドリヨン","SING&SMILE","スノーマン","DYE","なりすましゲンガー","ヒバナ","ヒビカセ","ブラックゴールド","ミラクルペイント","指切り","ありふれたせかいせいふく","アンハッピーリフレイン","大江戸ジュリアナイト","ゴーストルール","こちら、幸福安心委員会です。","孤独の果て -extend edition-","ジターバグ","Sweet Devil","砂の惑星","テオ","初音ミクの消失","秘密警察","妄想スケッチ","リンちゃんなう!","ローリンガール","ロキ","ロミオとシンデレラ","エンヴィキャットウォーク","骸骨楽団とリリア","サイハテ","ジグソーパズル","千本桜","ピアノ×フォルテ×スキャンダル","Blackjack","ぽっぴっぽー","裏表ラバーズ","Sadistic.Music∞Factory","デンパラダイム","二次元ドリームフィーバー","ネガポジ*コンティニューズ","初音ミクの激唱","ワールズエンド・ダンスホール","ココロ","システマティック・ラヴ","Knife","二息歩行","PIANOGIRL","夢喰い白黒バク"};
int SCREEN_X; int SCREEN_X;
int SCREEN_Y; int SCREEN_Y;
int WINDOW_X; int WINDOW_X;
@ -107,7 +112,6 @@ public class MyRobot{
if (OnResultsScreen() && !recordedResults && !recordingResults && results.size()==0) { if (OnResultsScreen() && !recordedResults && !recordingResults && results.size()==0) {
lastSongSelectTime=System.currentTimeMillis(); lastSongSelectTime=System.currentTimeMillis();
//1885,761
if (eyeTrackingSceneOn) { if (eyeTrackingSceneOn) {
eyeTrackingSceneOn=false; eyeTrackingSceneOn=false;
gotoxy(800,64); gotoxy(800,64);
@ -115,6 +119,7 @@ public class MyRobot{
gotoxy(1870,761); gotoxy(1870,761);
click(); click();
} }
//1885,761
//System.out.println(typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,451,115,26)))); //System.out.println(typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,451,115,26))));
//System.out.println(typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,484,115,26)))); //System.out.println(typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,484,115,26))));
//System.out.println(typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,518,115,26)))); //System.out.println(typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,518,115,26))));
@ -141,7 +146,7 @@ public class MyRobot{
if (cool==-1 || fine==-1 || safe==-1 || sad==-1 || worst==-1 || percent==-0.01f) { if (cool==-1 || fine==-1 || safe==-1 || sad==-1 || worst==-1 || percent==-0.01f) {
System.out.println("Waiting for results to populate..."); System.out.println("Waiting for results to populate...");
} else } else
if (cool!=lastcool || lastfine!=fine || lastsafe!=safe || lastsad!=sad || lastworst!=worst || lastpercent!=percent){ if (cool!=lastcool || lastfine!=fine || lastsafe!=safe || lastsad!=sad || lastworst!=worst /*|| lastpercent!=percent*/){
System.out.println("Results for "+selectedSong.title+" "+difficulty+": "+cool+"/"+fine+"/"+safe+"/"+sad+"/"+worst+" "+percent+"%"); System.out.println("Results for "+selectedSong.title+" "+difficulty+": "+cool+"/"+fine+"/"+safe+"/"+sad+"/"+worst+" "+percent+"%");
File songFolder = new File(selectedSong.title+"/"+difficulty); File songFolder = new File(selectedSong.title+"/"+difficulty);
if (!songFolder.exists()) { if (!songFolder.exists()) {
@ -180,72 +185,79 @@ public class MyRobot{
click(); click();
} }
} }
} else { } else {
if (results.size()>0 && System.currentTimeMillis()-5000>lastSongSelectTime) { if (results.size()>0 && System.currentTimeMillis()-5000>lastSongSelectTime) {
recordingResults=true; recordingResults=true;
MYROBOT.setAutoDelay(0); MYROBOT.setAutoDelay(0);
MYROBOT.keyPress(KeyEvent.VK_ALT); MYROBOT.keyPress(KeyEvent.VK_ALT);
MYROBOT.keyPress(KeyEvent.VK_TAB);
MYROBOT.keyRelease(KeyEvent.VK_ALT);
MYROBOT.setAutoDelay(5000);
MYROBOT.keyRelease(KeyEvent.VK_TAB);
boolean first=true;
for (Result r : results) {
if (!first) {
MYROBOT.setAutoDelay(5000);
} else {
first=false;
MYROBOT.setAutoDelay(100);
TYPE_DELAY=50;
}
StringSelection selection = new StringSelection((r.songName.equalsIgnoreCase("PIANOGIRL"))?"PIANO*GIRL":r.songName);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, selection);
MYROBOT.keyPress(KeyEvent.VK_CONTROL);
MYROBOT.keyPress(KeyEvent.VK_V);
MYROBOT.keyRelease(KeyEvent.VK_V);
MYROBOT.keyRelease(KeyEvent.VK_CONTROL);
MYROBOT.setAutoDelay(100);
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.cool));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.fine));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.safe));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.sad));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.worst));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(r.difficulty);
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Float.toString(r.percent));
MYROBOT.keyPress(KeyEvent.VK_TAB); MYROBOT.keyPress(KeyEvent.VK_TAB);
MYROBOT.keyRelease(KeyEvent.VK_ALT);
MYROBOT.setAutoDelay(250);
MYROBOT.keyRelease(KeyEvent.VK_TAB); MYROBOT.keyRelease(KeyEvent.VK_TAB);
sleep(2000);
boolean first=true;
for (Result r : results) {
if (!first) {
sleep(5000);
} else {
first=false;
}
type(r.songName);
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.cool));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.fine));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.safe));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.sad));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.worst));
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(r.difficulty);
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Float.toString(r.percent));
MYROBOT.keyPress(KeyEvent.VK_TAB);
MYROBOT.keyRelease(KeyEvent.VK_TAB);
MYROBOT.setAutoDelay(0);
MYROBOT.keyPress(KeyEvent.VK_CONTROL);
MYROBOT.keyPress(KeyEvent.VK_ALT);
MYROBOT.keyPress(KeyEvent.VK_SHIFT);
MYROBOT.keyPress(KeyEvent.VK_1);
MYROBOT.keyRelease(KeyEvent.VK_1);
MYROBOT.keyRelease(KeyEvent.VK_CONTROL);
MYROBOT.keyRelease(KeyEvent.VK_ALT);
MYROBOT.keyRelease(KeyEvent.VK_SHIFT);
}
results.clear();
sleep(1000);
MYROBOT.setAutoDelay(0); MYROBOT.setAutoDelay(0);
MYROBOT.keyPress(KeyEvent.VK_CONTROL);
MYROBOT.keyPress(KeyEvent.VK_ALT); MYROBOT.keyPress(KeyEvent.VK_ALT);
MYROBOT.keyPress(KeyEvent.VK_TAB); MYROBOT.keyPress(KeyEvent.VK_SHIFT);
MYROBOT.keyPress(KeyEvent.VK_1);
MYROBOT.keyRelease(KeyEvent.VK_1);
MYROBOT.keyRelease(KeyEvent.VK_CONTROL);
MYROBOT.keyRelease(KeyEvent.VK_ALT); MYROBOT.keyRelease(KeyEvent.VK_ALT);
MYROBOT.setAutoDelay(250); MYROBOT.keyRelease(KeyEvent.VK_SHIFT);
MYROBOT.keyRelease(KeyEvent.VK_TAB);
recordingResults=false;
} }
results.clear();
sleep(1000);
MYROBOT.setAutoDelay(0);
MYROBOT.keyPress(KeyEvent.VK_ALT);
MYROBOT.keyPress(KeyEvent.VK_TAB);
MYROBOT.keyRelease(KeyEvent.VK_ALT);
MYROBOT.setAutoDelay(250);
MYROBOT.keyRelease(KeyEvent.VK_TAB);
recordingResults=false;
}
if (!OnResultsScreen() && recordedResults) {
recordedResults=false;
} }
} else {
if (!OnResultsScreen() && recordedResults) {
recordedResults=false;
} }
} }
} }
//572,453 //572,453
//Red: 100-200, Blue: 200-255 Purple (EXEX) //Red: 100-200, Blue: 200-255 Purple (EXEX)
//Red: 150-255, Green: < 50 Blue: < 50 (EX) //Red: 150-255, Green: < 50 Blue: < 50 (EX)
//Red: 175-225, Green: 135-175 Blue: < 50 (Hard) //Red: 175-225, Green: 135-175 Blue: < 50 (Hard)
} }
private boolean OnResultsScreen() { private boolean OnResultsScreen() {
Color c1 = new Color(MYROBOT.createScreenCapture(new Rectangle(602,217,2,2)).getRGB(0, 0)); Color c1 = new Color(MYROBOT.createScreenCapture(new Rectangle(602,217,2,2)).getRGB(0, 0));
@ -413,9 +425,68 @@ public class MyRobot{
//p.getGraphics().drawImage(MYROBOT.createScreenCapture(new Rectangle(1205,553,160,26)), 0, i+=26, f); //p.getGraphics().drawImage(MYROBOT.createScreenCapture(new Rectangle(1205,553,160,26)), 0, i+=26, f);
//p.getGraphics().drawImage(MYROBOT.createScreenCapture(new Rectangle(1205,583,160,26)), 0, i+=26, f); //p.getGraphics().drawImage(MYROBOT.createScreenCapture(new Rectangle(1205,583,160,26)), 0, i+=26, f);
//p.getGraphics().drawImage(MYROBOT.createScreenCapture(new Rectangle(1428,361,128,30)), 0, i+=26, f); //p.getGraphics().drawImage(MYROBOT.createScreenCapture(new Rectangle(1428,361,128,30)), 0, i+=26, f);
RunTests();
BotMain(); BotMain();
} }
void RunTests() {
//418,204
/*int cool = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,451,115,26)),new File(tmp,"cool"));
int fine = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,484,115,26)),new File(tmp,"fine"));
int safe = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,518,115,26)),new File(tmp,"safe"));
int sad = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,553,115,26)),new File(tmp,"sad"));
int worst = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,583,115,26)),new File(tmp,"worst"));
float percent = (float)typeface2.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1428,361,128,30)),new File(tmp,"percent"))/100f;*/
selectedSong=new SongData("test",new Color[] {});
difficulty="EXEX";
RunTest("shake it!_EXplay_568_88_8_4_7_96.03.png",580,80,0,4,7,95.03f);
RunTest("え?あぁ、そう。_EXEXplay_499_121_11_9_43_77.11.png",439,121,11,5,43,77.11f);
RunTest("サマーアイドル_EXplay_959_56_19_5_10_81.32.png",363,58,15,5,10,84.32f);
RunTest("テレカクシ思春期_EXplay_44_108_7_4_18_81.8.png",447,109,7,4,16,84.80f);
RunTest("どういうことなの!?_EXplay_449_85_3_0_3_95.01.png",448,85,2,0,3,95.01f);
RunTest("天樂_EXplay_361_58_9_4_11_92.67.png",351,56,8,4,11,92.67f);
RunTest("番凩_EXEXplay_41_110_1_10_21_77.76.png",431,110,17,10,31,77.79f);
RunTest("結ンデ開イテ羅刹ト骸_EXEXplay_47_123_10_5_46_74.19.png",471,123,10,5,46,74.19f);
}
void RunTest(String _img,int _cool,int _fine, int _safe, int _sad, int _worst, float _percent) {
System.out.println("Running test "+_img);
long startTime = System.currentTimeMillis();
String testdir="testsuite";
Point offset = new Point(418,204);
File tmp = new File("tmp");
if (tmp.exists()) {
FileUtils.deleteFile(tmp);
} else {
tmp.mkdir();
}
BufferedImage img=null;
try {
img = ImageIO.read(new File(testdir,_img));
} catch (IOException e) {
e.printStackTrace();
}
int cool = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,451-offset.y,115,26)),new File(tmp,"cool"));
int fine = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,484-offset.y,115,26)),new File(tmp,"fine"));
int safe = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,518-offset.y,115,26)),new File(tmp,"safe"));
int sad = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,553-offset.y,115,26)),new File(tmp,"sad"));
int worst = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,583-offset.y,115,26)),new File(tmp,"worst"));
float percent = (float)typeface2.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1428-offset.x,361-offset.y,128,30)),new File(tmp,"percent"))/100f;
assert cool == _cool : "Expected cool count to be "+_cool+", got "+cool;
assert fine == _fine : "Expected fine count to be "+_fine+", got "+fine;
assert safe == _safe : "Expected safe count to be "+_safe+", got "+safe;
assert sad == _sad : "Expected sad count to be "+_sad+", got "+sad;
assert worst == _worst : "Expected worst count to be "+_worst+", got "+worst;
assert percent == _percent : "Expected percent to be "+_percent+", got "+percent;
System.out.println(" Passed ("+(System.currentTimeMillis()-startTime)+"ms)!");
}
boolean isOnSongSelect() { boolean isOnSongSelect() {
Color c = new Color(MYROBOT.createScreenCapture(new Rectangle(1255,824,20,20)).getRGB(10, 10)); Color c = new Color(MYROBOT.createScreenCapture(new Rectangle(1255,824,20,20)).getRGB(10, 10));
return c.getRed()==43 && c.getGreen()==88 && c.getBlue()==213; return c.getRed()==43 && c.getGreen()==88 && c.getBlue()==213;

@ -12,6 +12,7 @@ import java.util.List;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import sig.utils.FileUtils;
import sig.utils.ImageUtils; import sig.utils.ImageUtils;
public class TypeFace { public class TypeFace {
@ -23,7 +24,13 @@ public class TypeFace {
int red_minthreshold = 0; int red_minthreshold = 0;
int blue_maxthreshold = 255; int blue_maxthreshold = 255;
int green_maxthreshold = 150; int green_maxthreshold = 150;
int red_maxthreshold = 100; int red_maxthreshold = 126;
int blue_fillminthreshold = 75;
int green_fillminthreshold = 0;
int red_fillminthreshold = 0;
int blue_fillmaxthreshold = 255;
int green_fillmaxthreshold = 150;
int red_fillmaxthreshold = 100;
boolean darkFillCheck = true; boolean darkFillCheck = true;
Color[][] numbers = new Color[WIDTH*HEIGHT][NUMBER_COUNT]; Color[][] numbers = new Color[WIDTH*HEIGHT][NUMBER_COUNT];
BufferedImage baseImg; BufferedImage baseImg;
@ -54,7 +61,8 @@ public class TypeFace {
final boolean DEBUG_IMG = false; final boolean DEBUG_IMG = false;
int iterations=0;
while (X<img.getWidth()) { while (X<img.getWidth()) {
boolean success=true; boolean success=true;
Color p = new Color(img.getRGB(X, midY),true); Color p = new Color(img.getRGB(X, midY),true);
@ -66,14 +74,6 @@ public class TypeFace {
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) { p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) {
//We found a dark pixel. //We found a dark pixel.
state=1; state=1;
if (darkFillCheck) {
success = fillDark(img,X,midY,0,0);
if (!success) {
//We're done.
X=img.getWidth();
break;
}
}
if (DEBUG_IMG) { if (DEBUG_IMG) {
try { try {
BufferedImage img2 = ImageUtils.copyBufferedImage(img); BufferedImage img2 = ImageUtils.copyBufferedImage(img);
@ -83,6 +83,14 @@ public class TypeFace {
e.printStackTrace(); e.printStackTrace();
} }
} }
if (darkFillCheck) {
success = fillDark(img,X,midY,0,0);
if (!success) {
//We're done.
X=img.getWidth();
break;
}
}
} }
}break; }break;
case 1:{ case 1:{
@ -126,39 +134,45 @@ public class TypeFace {
}break; }break;
case 3:{ case 3:{
//Figure out which number in the typeface it best represents. //Figure out which number in the typeface it best represents.
if (numberImg.getHeight()>numberImg.getWidth()) { numberImg = ImageUtils.toBufferedImage(numberImg.getScaledInstance(WIDTH, HEIGHT, Image.SCALE_FAST));
numberImg = ImageUtils.toBufferedImage(numberImg.getScaledInstance(-1, HEIGHT, Image.SCALE_FAST));
} else {
numberImg = ImageUtils.toBufferedImage(numberImg.getScaledInstance(WIDTH, -1, Image.SCALE_FAST));
}
//System.out.println(numberImg.getWidth()+"x"+numberImg.getHeight()); //System.out.println(numberImg.getWidth()+"x"+numberImg.getHeight());
int[] hits = new int[NUMBER_COUNT]; int[] hits = new int[NUMBER_COUNT];
double highestRatio = 0; double highestRatio = 0;
int highest = 0; int highest = 0;
for (int k=0;k<NUMBER_COUNT;k++) { for (int k=0;k<NUMBER_COUNT;k++) {
BufferedImage img2 = ImageUtils.copyBufferedImage(numberImg);
for (int i=0;i<WIDTH;i++) { for (int i=0;i<WIDTH;i++) {
for (int j=0;j<HEIGHT;j++) { for (int j=0;j<HEIGHT;j++) {
if (i<numberImg.getWidth() && if (i<numberImg.getWidth() &&
j<numberImg.getHeight()) { j<numberImg.getHeight()) {
Color pixel = new Color(numberImg.getRGB(i, j)); Color pixel = new Color(numberImg.getRGB(i, j));
if (numbers[i*HEIGHT+j][k].getRed()==pixel.getRed() && numbers[i*HEIGHT+j][k].getRed()==pixel.getGreen() && numbers[i*HEIGHT+j][k].getBlue()==pixel.getBlue()) { if (numbers[i*HEIGHT+j][k].getRed()==pixel.getRed() && numbers[i*HEIGHT+j][k].getGreen()==pixel.getGreen() && numbers[i*HEIGHT+j][k].getBlue()==pixel.getBlue()) {
hits[k]++; hits[k]++;
//System.out.println("Hit for "+((k+1)%NUMBER_COUNT)+"! "+hits[k] + "/"+numbers[i*HEIGHT+j][k]+"/"+pixel); //System.out.println("Hit for "+((k+1)%NUMBER_COUNT)+"! "+hits[k] + "/"+numbers[i*HEIGHT+j][k]+"/"+pixel);
if ((double)hits[k]/(WIDTH*HEIGHT)>highestRatio) { if ((double)hits[k]/(WIDTH*HEIGHT)>highestRatio) {
highestRatio = (double)(hits[k])/(WIDTH*HEIGHT); highestRatio= (double)(hits[k])/(WIDTH*HEIGHT);
highest=k; highest=k;
} }
} else {
if (pixel.equals(Color.WHITE)) {
img2.setRGB(i, j, Color.BLUE.getRGB());
} else {
img2.setRGB(i, j, Color.RED.getRGB());
}
//FileUtils.logToFile("Pixel difference: "+numbers[i*HEIGHT+j][k]+"/"+pixel, new File(saveLoc,(iterations)+".txt").getPath());
} }
} }
} }
} }
} FileUtils.logToFile(((k+1)%NUMBER_COUNT)+":"+((double)(hits[k])/(WIDTH*HEIGHT)), new File(saveLoc,(iterations)+".txt").getPath());
try { try {
ImageIO.write(numberImg,"png",new File(saveLoc,((highest+1)%NUMBER_COUNT)+".png")); ImageIO.write(img2,"png",new File(saveLoc,(iterations)+"_"+((k+1)%NUMBER_COUNT)+".png"));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
}
} }
//System.out.println("Matches closest to "+((highest+1)%NUMBER_COUNT)+" with "+highestRatio); //System.out.println("Matches closest to "+((highest+1)%NUMBER_COUNT)+" with "+highestRatio);
iterations++;
extractedNumbers+=Integer.toString((highest+1)%NUMBER_COUNT); extractedNumbers+=Integer.toString((highest+1)%NUMBER_COUNT);
state=4; state=4;
}break; }break;
@ -197,9 +211,9 @@ public class TypeFace {
Color p = null; Color p = null;
if (startX+x+1<img.getWidth()) { if (startX+x+1<img.getWidth()) {
p = new Color(img.getRGB(startX+x+1, startY+y)); p = new Color(img.getRGB(startX+x+1, startY+y));
if (p.getBlue()>blue_minthreshold && p.getBlue()<blue_maxthreshold && if (p.getBlue()>blue_fillminthreshold && p.getBlue()<blue_fillmaxthreshold &&
p.getGreen()>green_minthreshold && p.getGreen()<green_maxthreshold && p.getGreen()>green_fillminthreshold && p.getGreen()<green_fillmaxthreshold &&
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) { p.getRed()>red_fillminthreshold && p.getRed()<red_fillmaxthreshold) {
fillDark(img,startX,startY,x+1,y); fillDark(img,startX,startY,x+1,y);
} }
} else { } else {
@ -207,9 +221,9 @@ public class TypeFace {
} }
if (startX+x-1>0) { if (startX+x-1>0) {
p = new Color(img.getRGB(startX+x-1, startY+y)); p = new Color(img.getRGB(startX+x-1, startY+y));
if (p.getBlue()>blue_minthreshold && p.getBlue()<blue_maxthreshold && if (p.getBlue()>blue_fillminthreshold && p.getBlue()<blue_fillmaxthreshold &&
p.getGreen()>green_minthreshold && p.getGreen()<green_maxthreshold && p.getGreen()>green_fillminthreshold && p.getGreen()<green_fillmaxthreshold &&
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) { p.getRed()>red_fillminthreshold && p.getRed()<red_fillmaxthreshold) {
fillDark(img,startX,startY,x-1,y); fillDark(img,startX,startY,x-1,y);
} }
} else { } else {
@ -217,9 +231,9 @@ public class TypeFace {
} }
if (startY+y+1<img.getHeight()) { if (startY+y+1<img.getHeight()) {
p = new Color(img.getRGB(startX+x, startY+y+1)); p = new Color(img.getRGB(startX+x, startY+y+1));
if (p.getBlue()>blue_minthreshold && p.getBlue()<blue_maxthreshold && if (p.getBlue()>blue_fillminthreshold && p.getBlue()<blue_fillmaxthreshold &&
p.getGreen()>green_minthreshold && p.getGreen()<green_maxthreshold && p.getGreen()>green_fillminthreshold && p.getGreen()<green_fillmaxthreshold &&
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) { p.getRed()>red_fillminthreshold && p.getRed()<red_fillmaxthreshold) {
fillDark(img,startX,startY,x,y+1); fillDark(img,startX,startY,x,y+1);
} }
} else { } else {
@ -227,9 +241,9 @@ public class TypeFace {
} }
if (startY+y-1>0) { if (startY+y-1>0) {
p = new Color(img.getRGB(startX+x, startY+y-1)); p = new Color(img.getRGB(startX+x, startY+y-1));
if (p.getBlue()>blue_minthreshold && p.getBlue()<blue_maxthreshold && if (p.getBlue()>blue_fillminthreshold && p.getBlue()<blue_fillmaxthreshold &&
p.getGreen()>green_minthreshold && p.getGreen()<green_maxthreshold && p.getGreen()>green_fillminthreshold && p.getGreen()<green_fillmaxthreshold &&
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) { p.getRed()>red_fillminthreshold && p.getRed()<red_fillmaxthreshold) {
fillDark(img,startX,startY,x,y-1); fillDark(img,startX,startY,x,y-1);
} }
} else { } else {
@ -301,7 +315,7 @@ public class TypeFace {
int offsetX = 0; int offsetX = 0;
int finalHeight = maxY-minY+1; int finalHeight = maxY-minY+1;
int offsetY = 0; int offsetY = 0;
if (finalWidth > finalHeight) { /*if (finalWidth > finalHeight) {
//Add padding for height. //Add padding for height.
offsetY += (finalWidth-finalHeight)/2; offsetY += (finalWidth-finalHeight)/2;
finalHeight+= offsetY*2; finalHeight+= offsetY*2;
@ -310,7 +324,7 @@ public class TypeFace {
//Add padding for width. //Add padding for width.
offsetX += (finalHeight-finalWidth)/2; offsetX += (finalHeight-finalWidth)/2;
finalWidth+= offsetX*2; finalWidth+= offsetX*2;
} }*/
BufferedImage bufferedImage = new BufferedImage(finalWidth, finalHeight, BufferedImage bufferedImage = new BufferedImage(finalWidth, finalHeight,
BufferedImage.TYPE_INT_RGB); BufferedImage.TYPE_INT_RGB);

@ -2,6 +2,7 @@ package sig.utils;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Image; import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
public class ImageUtils { public class ImageUtils {
@ -39,6 +40,44 @@ public class ImageUtils {
bGr.drawImage(img, 0, 0, null); bGr.drawImage(img, 0, 0, null);
bGr.dispose(); bGr.dispose();
// Return the buffered image
return bimage;
}
public static BufferedImage cropImage(BufferedImage img,Rectangle offset)
{
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(offset.width, offset.height, BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, -offset.x, -offset.y, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
public static BufferedImage copyBufferedImages(BufferedImage...img)
{
int widthSum=0;
int maxHeight=0;
for (int i=0;i<img.length;i++) {
widthSum+=img[i].getWidth();
maxHeight=Math.max(maxHeight, img[i].getHeight());
}
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(widthSum, maxHeight, BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
int X=0;
for (int i=0;i<img.length;i++) {
bGr.drawImage(img[i], X, 0, null);
X+=img[i].getWidth();
}
bGr.dispose();
// Return the buffered image // Return the buffered image
return bimage; return bimage;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Loading…
Cancel
Save