Finish implementing new image detection for lossy and scaled images.

This commit is contained in:
Joshua Sigona 2020-07-20 05:40:04 +09:00
parent 2bc5d9987f
commit 982f0a03e9
216 changed files with 595 additions and 175 deletions

File diff suppressed because one or more lines are too long

110
colorData.old Normal file

File diff suppressed because one or more lines are too long

1
command Normal file
View File

@ -0,0 +1 @@
select * from songs where name!='1/6 -out of the gravity-' and name!='1925' and name!='39' and name!='39みゅーじっく' and name!='ACUTE' and name!='AFTER BURNER' and name!='Blackjack' and name!='Catch the Wave' and name!='Dear' and name!='DECORATOR' and name!='DYE' and name!='erase or zero' and name!='Fire◎Flower' and name!='FREELY TOMORROW' and name!='from Y to Y' and name!='Gemini' and name!='Glory 3usi9' and name!='Hand in Hand' and name!='Hello, Worker' and name!='Just Be Friends' and name!='Knife' and name!='LIKE THE WIND' and name!='LOL -lots of laugh-' and name!='magnet' and name!='No Logic' and name!='Nostalogic' and name!='ODDS&ENDS' and name!='on the rocks' and name!='packaged' and name!='Palette' and name!='PIANO*GIRL' and name!='Rosary Pale' and name!='Sadistic.Music∞Factory' and name!='shake it!' and name!='SING&SMILE' and name!='soundless voice' and name!=E'SPiCa -39\'s Giving Day Edition-' and name!='Starduster' and name!='StargazeR' and name!='Sweet Devil' and name!='Tell Your World' and name!='The secret garden' and name!='Weekender Girl' and name!='WORLD'S END UMBRELLA' and name!='Yellow' and name!='あなたの歌姫' and name!='ありふれたせかいせいふく' and name!='えれくとりっく・えんじぇぅ' and name!='え?あぁ、そう。' and name!='からくりピエロ' and name!='こちら、幸福安心委員会です。' and name!='どういうことなの!?' and name!='どりーみんチュチュ' and name!='なりすましゲンガー' and name!='はじめまして地球人さん' and name!='ぽっぴっぽー' and name!='みくみくにしてあげる♪' and name!='ゆめゆめ' and name!='アカツキアライヴァル' and name!='アゲアゲアゲイン' and name!='アマツキツネ' and name!='アンハッピーリフレイン' and name!='インタビュア' and name!='エイリアンエイリアン' and name!='エレクトロサチュレイタ' and name!='エンヴィキャットウォーク' and name!='カラフル×メロディ' and name!='カンタレラ' and name!='キャットフード' and name!='クローバー♣クラブ' and name!='ココロ' and name!='ゴーストルール' and name!='サイハテ' and name!='サマーアイドル' and name!='サンドリヨン' and name!='システマティック・ラヴ' and name!='ジグソーパズル' and name!='ジターバグ' and name!='スイートマジック' and name!='スキキライ' and name!='スノーマン' and name!='タイムマシン' and name!='ダブルラリアット' and name!='テオ' and name!='テレカクシ思春期' and name!='デンパラダイム' and name!='トリコロール・エア・ライン' and name!='トリノコシティ' and name!='ネガポジ*コンティニューズ' and name!='ネトゲ廃人シュプレヒコール' and name!='ハイハハイニ' and name!='ハジメテノオト' and name!='ヒバナ' and name!='ヒビカセ' and name!='ピアノ×フォルテ×スキャンダル' and name!='ブラック★ロックシューター' and name!='ブラックゴールド' and name!='ブレス・ユア・ブレス' and name!='ミラクルペイント' and name!='メテオ' and name!='メランコリック' and name!='メルト' and name!='モノクロ∞ブルースカイ' and name!='リモコン' and name!='リンちゃんなう!' and name!='リンリンシグナル' and name!='ルカルカ★ナイトフィーバー' and name!='ロキ' and name!='ロミオとシンデレラ' and name!='ローリンガール' and name!='ワールズエンド・ダンスホール' and name!='ワールドイズマイン' and name!='二息歩行' and name!='二次元ドリームフィーバー' and name!='初めての恋が終わる時' and name!='初音ミクの消失 -DEAD END-' and name!='初音ミクの激唱' and name!='千年の独奏歌' and name!='千本桜' and name!='右肩の蝶' and name!='壊セ壊セ' and name!='多重未来のカルテットQUARTET THEME' and name!='夢喰い白黒バク' and name!='大江戸ジュリアナイト' and name!='天樂' and name!='妄想スケッチ' and name!='孤独の果て' and name!='巨大少女' and name!='忘却心中' and name!='恋は戦争' and name!='恋スルVOC@LOID' and name!='愛言葉' and name!='指切り' and name!='東京テディベア' and name!='桜ノ雨' and name!='歌に形はないけれど' and name!='深海シティアンダーグラウンド' and name!='深海少女' and name!='炉心融解' and name!='番凩' and name!='白い雪のプリンセスは' and name!='砂の惑星' and name!='神曲' and name!='秘密警察' and name!='積乱雲グラフィティ' and name!='結ンデ開イテ羅刹ト骸' and name!='裏表ラバーズ' and name!='骸骨楽団とリリア' and name!='*ハロー、プラネット。 (I.M.PLSE-EDIT)';

BIN
image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
resources/Blackjack.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

BIN
resources/DYE.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

BIN
resources/Knife.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 KiB

BIN
resources/PIANOGIRL.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

BIN
resources/Sweet Devil.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

BIN
resources/サイハテ.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 KiB

View File

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

BIN
resources/テオ.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

BIN
resources/ヒバナ.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 KiB

BIN
resources/ロキ.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

BIN
resources/千本桜.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

BIN
resources/君の体温.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

BIN
resources/指切り.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 KiB

BIN
resources/砂の惑星.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

BIN
resources/秘密警察.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

View File

@ -1,8 +1,11 @@
package com.example.demo; package com.example.demo;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.filter.CharacterEncodingFilter;
import sig.TypeFace; import sig.TypeFace;
import sig.utils.FileUtils; import sig.utils.FileUtils;
@ -17,20 +20,32 @@ import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLDecoder;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
@RestController @RestController
public class Controller { public class Controller {
static TypeFace typeface1,typeface2; @Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setForceEncoding(true);
characterEncodingFilter.setEncoding("UTF-8");
registrationBean.setFilter(characterEncodingFilter);
return registrationBean;
}
boolean textFailPixel(BufferedImage img) { public static boolean textFailPixel(BufferedImage img) {
Color failPixel = new Color(img.getRGB(0, 0)); Color failPixel = new Color(img.getRGB(0, 0));
//System.out.println(failPixel); //System.out.println(failPixel);
//r=128,g=5,b=232 //r=128,g=5,b=232
@ -42,23 +57,13 @@ public class Controller {
HashMap<String,String> data = new HashMap<>(); HashMap<String,String> data = new HashMap<>();
//System.out.println(new File(".").getAbsolutePath()); //System.out.println(new File(".").getAbsolutePath());
try { try {
System.out.println(url);
downloadFileFromUrl(url,"temp"); downloadFileFromUrl(url,"temp");
BufferedImage img1 = null;
BufferedImage img2 = null;
typeface1 = null;
typeface2=null;
//BufferedImage img = ImageUtils.toBufferedImage(ImageIO.read(new File("temp")).getScaledInstance(1227, 690, Image.SCALE_SMOOTH)); //BufferedImage img = ImageUtils.toBufferedImage(ImageIO.read(new File("temp")).getScaledInstance(1227, 690, Image.SCALE_SMOOTH));
BufferedImage img = ImageIO.read(new File("temp")); BufferedImage img = ImageIO.read(new File("temp"));
try { if (img.getWidth()!=1200) {
img1 = ImageUtils.toCompatibleImage(ImageIO.read(new File("typeface1.png"))); //Resize.
img2 = ImageUtils.toCompatibleImage(ImageIO.read(new File("typeface2.png"))); img = ImageUtils.toBufferedImage(ImageIO.read(new File("temp")).getScaledInstance(1200, 675, Image.SCALE_SMOOTH));
typeface1 = new TypeFace(img1);
typeface2 = new TypeFace(img2);
typeface2.green_minthreshold=typeface2.blue_minthreshold=100;
typeface2.green_maxthreshold=typeface2.blue_maxthreshold=200;
typeface2.darkFillCheck=false;
} catch (IOException e1) {
e1.printStackTrace();
} }
Point offset = new Point(418,204); Point offset = new Point(418,204);
File tmp = new File("tmp"); File tmp = new File("tmp");
@ -68,12 +73,12 @@ public class Controller {
tmp.mkdir(); tmp.mkdir();
} }
String song = getSongTitle(img); String song = getSongTitle(img);
int cool = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(790,242,118,26)),new File(tmp,"cool")); int cool = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(790,242,118,26)),new File(tmp,"cool"));
int fine = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,274,118,26)),new File(tmp,"fine")); int fine = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,274,118,26)),new File(tmp,"fine"));
int safe = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,308,118,26)),new File(tmp,"safe")); int safe = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,308,118,26)),new File(tmp,"safe"));
int sad = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,341,118,26)),new File(tmp,"sad")); int sad = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,341,118,26)),new File(tmp,"sad"));
int worst = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,372,118,26)),new File(tmp,"worst")); int worst = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,372,118,26)),new File(tmp,"worst"));
float percent = (float)typeface2.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(986,154,122,31)),new File(tmp,"percent"))/100f; float percent = DemoApplication.typeface2.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(986,154,122,31)),new File(tmp,"percent"))/100f;
boolean fail = textFailPixel(ImageUtils.cropImage(img, new Rectangle(514,171,1,1))); boolean fail = textFailPixel(ImageUtils.cropImage(img, new Rectangle(514,171,1,1)));
ImageIO.write(img,"png",new File("tmp/image.png")); ImageIO.write(img,"png",new File("tmp/image.png"));
@ -91,22 +96,35 @@ public class Controller {
return data; return data;
} }
private String getSongTitle(BufferedImage img) { public static String getSongTitle(BufferedImage img) {
int matching = 0; final int THRESHOLD=1;
float lowestMatching = Integer.MAX_VALUE;
SongData matchingSong = null;
//There are 2304 pixels total. Once 2188 match, we'll call it good. //There are 2304 pixels total. Once 2188 match, we'll call it good.
for (SongData song : DemoApplication.songs) { for (SongData song : DemoApplication.songs) {
float matching = 0;
for (int y=0;y<288;y++) { for (int y=0;y<288;y++) {
for (int x=0;x<8;x++) { for (int x=0;x<8;x++) {
if (song.data[(y*8)+x].getRGB()==img.getRGB(x+352, y+288)) { Color p2 = song.data[(y*8)+x];
matching++; Color p1 = new Color(img.getRGB(x+352, y+288));
} matching+=Math.sqrt(Math.pow(p2.getRed()-p1.getRed(), 2)+Math.pow(p2.getGreen()-p1.getGreen(), 2)+Math.pow(p2.getBlue()-p1.getBlue(), 2));
if (matching>2188) {
return song.song;
} }
} }
if (matching<lowestMatching) {
lowestMatching=matching;
matchingSong = song;
} }
/*try {
PrintStream out = new PrintStream(System.out, true, "UTF-8");
out.println("Comparing to "+song.song+": "+matching);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}*/
} }
return null; //System.out.println("Lowest: "+lowestMatching);
return matchingSong.song;
} }
public static void downloadFileFromUrl(String url, String file) throws IOException{ public static void downloadFileFromUrl(String url, String file) throws IOException{

View File

@ -1,22 +1,36 @@
package com.example.demo; package com.example.demo;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; 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.List; import java.util.List;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.util.Assert;
import sig.TypeFace;
import sig.utils.FileUtils; import sig.utils.FileUtils;
import sig.utils.ImageUtils;
@SpringBootApplication @SpringBootApplication
public class DemoApplication { public class DemoApplication {
public static List<SongData> songs = new ArrayList<SongData>(); public static List<SongData> songs = new ArrayList<SongData>();
public static TypeFace typeface1;
public static TypeFace typeface2;
static Integer totalConfidence = 0;
static TestResult result = null;
static Integer[]controls = new Integer[]{150, 255, 153, 255, 159, 255, 0, 159, 3, 171, 8, 155};
static Integer[]lastControls = new Integer[]{150, 255, 153, 255, 159, 255, 0, 159, 3, 171, 8, 155};
static Integer generation = 30; //Confidence level.
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args); SpringApplication.run(DemoApplication.class, args);
@ -27,6 +41,9 @@ public class DemoApplication {
boolean first=true; boolean first=true;
try { try {
BufferedImage img = ImageIO.read(new File(dir,s)); BufferedImage img = ImageIO.read(new File(dir,s));
if (img.getWidth()!=1200) {
img = ImageUtils.toBufferedImage(img.getScaledInstance(1200, 675, Image.SCALE_SMOOTH));
}
for (int y=288;y<288+288;y++) { for (int y=288;y<288+288;y++) {
for (int x=352;x<352+8;x++) { for (int x=352;x<352+8;x++) {
if (!first) { if (!first) {
@ -42,12 +59,170 @@ public class DemoApplication {
e.printStackTrace(); e.printStackTrace();
} }
}*/ }*/
/*File dir = new File("resources");
StringBuilder sb = new StringBuilder();
for (String s : dir.list()) {
sb.append("and name!='").append(s.replace(".jpg","")).append("' ");
}
FileUtils.logToFile(sb.toString(), "command");*/
BufferedImage img1 = null;
BufferedImage img2 = null;
try {
img1 = ImageUtils.toCompatibleImage(ImageIO.read(new File("typeface1.png")));
img2 = ImageUtils.toCompatibleImage(ImageIO.read(new File("typeface2.png")));
typeface1 = new TypeFace(img1);
typeface2 = new TypeFace(img2);
typeface2.green_minthreshold=typeface2.blue_minthreshold=100;
typeface2.green_maxthreshold=typeface2.blue_maxthreshold=200;
typeface2.darkFillCheck=false;
} catch (IOException e1) {
e1.printStackTrace();
}
String[] str = FileUtils.readFromFile("colorData"); String[] str = FileUtils.readFromFile("colorData");
for (String s : str) { for (String s : str) {
songs.add(new SongData(s)); songs.add(new SongData(s));
} }
//System.out.println(songs);
RunTest("*ハロー、プラネット。 (I.M.PLSE-EDIT).jpg",336,128,24,6,93,58.85f,true);
RunTest("16 -out of the gravity-.jpg",554,45,1,0,1,101.36f,false);
RunTest("39.jpg",531,71,2,0,2,97.82f,false);
RunTest("39みゅーじっく.jpg",573,175,5,0,18,91.22f,false);
RunTest("1925.jpg",510,115,14,7,22,77.79f,false);
RunTest("ACUTE.jpg",478,64,1,1,5,95.76f,false);
RunTest("AFTER BURNER.jpg",370,113,25,16,30,68.76f,true);
RunTest("Blackjack.jpg",415,123,15,7,50,71.22f,false);
RunTest("Catch the Wave.jpg",603,72,0,0,1,100.65f,false);
RunTest("Dear.jpg",402,64,0,0,1,100.90f,false);
RunTest("DECORATOR.jpg",436,100,1,0,6,93.52f,false);
RunTest("Fire◎Flower.jpg",86.79f,false);
RunTest("DYE.jpg",530,106,7,2,13,84.77f,false);
RunTest("erase or zero.jpg",442,70,0,0,2,100.12f,false);
RunTest("FREELY TOMORROW.jpg",367,57,0,0,0,102.84f,false);
RunTest("from Y to Y.jpg",350,49,6,1,8,86.35f,false);
RunTest("Glory 3usi9.jpg",468,43,0,0,2,101.62f,false);
RunTest("Hand in Hand.jpg",401,54,1,0,3,97.58f,false);
RunTest("Hello, Worker.jpg",439,118,7,1,14,89.93f,false);
RunTest("Just Be Friends.jpg",510,107,6,0,12,89.38f,false);
RunTest("Knife.jpg",327,85,14,9,27,51.96f,true);
RunTest("LIKE THE WIND.jpg",330,144,20,9,20,72.06f,false);
RunTest("LOL -lots of laugh-.jpg",489,59,1,2,2,96.36f,false);
RunTest("magnet.jpg",435,101,18,4,35,76.98f,false);
RunTest("No Logic.jpg",491,101,11,5,15,86.32f,false);
System.out.println("All Tests passed!");
}
private static void ModifyResults() {
//generation+=result.count-1;
if (!result.passed) {
if (result.count-1>totalConfidence) {
lastControls = controls.clone();
totalConfidence = Math.max(result.count-1,totalConfidence);
System.out.println("Passed "+(result.count-1)+" test! Confidence:"+totalConfidence+" Storing lastControls: "+Arrays.toString(lastControls));
}
if (result.count-1<totalConfidence) {
//System.out.println("Restoring previous trial...");
controls = lastControls.clone();
}
if (generation.equals(0)) {
for (int i=0;i<controls.length;i+=2) {
controls[i]=(int)(Math.random()*255);
controls[i+1]=controls[i]+(int)(Math.random()*(255-controls[i]));
}
} else {
for (int i=0;i<controls.length;i++) {
if (Math.random()*generation<1) {
controls[i]=lastControls[i].intValue();
controls[i]+=(int)((Math.random()*(255*(1f/(generation))))-(255*(1f/(generation*2f))));
controls[i]=Math.max(controls[i], 0);
controls[i]=Math.min(255, controls[i]);
}
}
}
System.out.println(Arrays.toString(controls));
} else {
lastControls = controls.clone();
System.out.println("Passed with "+Arrays.toString(controls));
}
}
static void RunTest(String _img,float _percent,boolean _fail) {
long startTime = System.currentTimeMillis();
String testdir="resources";
Point offset = new Point(418,204);
File tmp = new File("tmp");
if (tmp.exists()) {
FileUtils.deleteFile(tmp);
}
tmp.mkdir();
BufferedImage img=null;
try {
img = ImageIO.read(new File(testdir,_img));
if (img.getWidth()!=1200) {
//Resize.
img = ImageUtils.toBufferedImage(ImageIO.read(new File(testdir,_img)).getScaledInstance(1200, 675, Image.SCALE_SMOOTH));
}
ImageIO.write(img,"png",new File("image.png"));
} catch (IOException e) {
e.printStackTrace();
}
String song = Controller.getSongTitle(img);
float percent = DemoApplication.typeface2.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(986,154,122,31)),new File(tmp,"percent"),false)/100f;
boolean fail = Controller.textFailPixel(ImageUtils.cropImage(img, new Rectangle(514,171,1,1)));
String _name = _img.replace(".jpg","");
song = (song.equalsIgnoreCase("PIANOGIRL"))?"PIANO*GIRL":(song.equalsIgnoreCase("16 -out of the gravity-"))?"1/6 -out of the gravity-":song;
_name = (_name.equalsIgnoreCase("PIANOGIRL"))?"PIANO*GIRL":(_name.equalsIgnoreCase("16 -out of the gravity-"))?"1/6 -out of the gravity-":_name;
Assert.isTrue(song.equalsIgnoreCase(_name),"Expected song name to be "+_name+", got "+song);
Assert.isTrue(percent == _percent,"Expected percent to be "+_percent+", got "+percent);
Assert.isTrue(fail == _fail,"Expected fail to be "+_fail+", got "+fail);
System.out.println(" Passed ("+(System.currentTimeMillis()-startTime)+"ms)!");
}
static void RunTest(String _img,int _cool,int _fine, int _safe, int _sad, int _worst, float _percent,boolean _fail) {
//System.out.println("Running test "+_img);
long startTime = System.currentTimeMillis();
String testdir="resources";
Point offset = new Point(418,204);
File tmp = new File("tmp");
if (tmp.exists()) {
FileUtils.deleteFile(tmp);
}
tmp.mkdir();
BufferedImage img=null;
try {
img = ImageIO.read(new File(testdir,_img));
if (img.getWidth()!=1200) {
//Resize.
img = ImageUtils.toBufferedImage(ImageIO.read(new File(testdir,_img)).getScaledInstance(1200, 675, Image.SCALE_SMOOTH));
}
ImageIO.write(img,"png",new File("image.png"));
} catch (IOException e) {
e.printStackTrace();
}
String song = Controller.getSongTitle(img);
int cool = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(790,242,118,26)),new File(tmp,"cool"),false);
int fine = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,274,118,26)),new File(tmp,"fine"),false);
int safe = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,308,118,26)),new File(tmp,"safe"),false);
int sad = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,341,118,26)),new File(tmp,"sad"),false);
int worst = DemoApplication.typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(792,372,118,26)),new File(tmp,"worst"),false);
float percent = DemoApplication.typeface2.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(986,154,122,31)),new File(tmp,"percent"),false)/100f;
boolean fail = Controller.textFailPixel(ImageUtils.cropImage(img, new Rectangle(514,171,1,1)));
String _name = _img.replace(".jpg","");
song = (song.equalsIgnoreCase("PIANOGIRL"))?"PIANO*GIRL":(song.equalsIgnoreCase("16 -out of the gravity-"))?"1/6 -out of the gravity-":song;
_name = (_name.equalsIgnoreCase("PIANOGIRL"))?"PIANO*GIRL":(_name.equalsIgnoreCase("16 -out of the gravity-"))?"1/6 -out of the gravity-":_name;
Assert.isTrue(song.equalsIgnoreCase(_name),"Expected song name to be "+_name+", got "+song);
Assert.isTrue(cool == _cool,"Expected cool count to be "+_cool+", got "+cool);
Assert.isTrue(fine == _fine,"Expected fine count to be "+_fine+", got "+fine);
Assert.isTrue(safe == _safe,"Expected safe count to be "+_safe+", got "+safe);
Assert.isTrue(sad == _sad,"Expected sad count to be "+_sad+", got "+sad);
Assert.isTrue(worst == _worst,"Expected worst count to be "+_worst+", got "+worst);
Assert.isTrue(percent == _percent,"Expected percent to be "+_percent+", got "+percent);
Assert.isTrue(fail == _fail,"Expected fail to be "+_fail+", got "+fail);
System.out.println(" Passed ("+(System.currentTimeMillis()-startTime)+"ms)!");
} }
} }

View File

@ -9,6 +9,7 @@ public class SongData {
public SongData(String parseStr) { public SongData(String parseStr) {
String[] split = parseStr.split(":"); String[] split = parseStr.split(":");
song = split[0]; song = split[0];
song = (song.equalsIgnoreCase("PIANOGIRL"))?"PIANO*GIRL":(song.equalsIgnoreCase("16 -out of the gravity-"))?"1/6 -out of the gravity-":song;
String[] colors = split[1].split(","); String[] colors = split[1].split(",");
data = new Color[colors.length]; data = new Color[colors.length];
for (int i=0;i<colors.length;i++) { for (int i=0;i<colors.length;i++) {

View File

@ -0,0 +1,12 @@
package com.example.demo;
public class TestResult {
public boolean passed;
public String message;
public int count;
public TestResult(boolean passed,int count,String message) {
this.passed=passed;
this.count=count;
this.message=message;
}
}

View File

@ -47,9 +47,38 @@ public class TypeFace {
} }
public int extractNumbersFromImage(BufferedImage img,File saveLoc) { public int extractNumbersFromImage(BufferedImage img,File saveLoc) {
return extractNumbersFromImage(img,saveLoc,false);
}
public int extractNumbersFromImage(BufferedImage img,File saveLoc,boolean debug) {
final boolean DEBUG_IMG = debug;
for (int x=0;x<img.getWidth();x++) {
for (int y=0;y<img.getHeight();y++) {
Color currentCol = new Color(img.getRGB(x, y));
if ((currentCol.getRed()>=0 && currentCol.getRed()<=100
&& currentCol.getGreen()>=0 && currentCol.getGreen()<=150
&& currentCol.getBlue()>=0 && currentCol.getBlue()<=150) ||
(currentCol.getRed()>=0 && currentCol.getRed()<=60
&& currentCol.getGreen()>=100 && currentCol.getGreen()<=140
&& currentCol.getBlue()>=120 && currentCol.getBlue()<=190)) {
img.setRGB(x, y, new Color(8,114,140).getRGB());
} else {
img.setRGB(x, y, Color.WHITE.getRGB());
}
}
}
if (!saveLoc.exists()) { if (!saveLoc.exists()) {
saveLoc.mkdirs(); saveLoc.mkdirs();
} }
try {
ImageIO.write(img,"png",new File(saveLoc,"img.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
int midY = img.getHeight()/2; int midY = img.getHeight()/2;
int X = 0; int X = 0;
@ -60,8 +89,6 @@ public class TypeFace {
BufferedImage numberImg = null; BufferedImage numberImg = null;
final boolean DEBUG_IMG = false;
int iterations=0; int iterations=0;
while (X<img.getWidth()) { while (X<img.getWidth()) {
@ -96,6 +123,7 @@ public class TypeFace {
}break; }break;
case 1:{ case 1:{
//Move right until light pixel. //Move right until light pixel.
//Check if next pixel is also a light pixel.
if (p.getBlue()>200 && p.getGreen()>200 && p.getRed()>200) { if (p.getBlue()>200 && p.getGreen()>200 && p.getRed()>200) {
state=2; state=2;
if (DEBUG_IMG) { if (DEBUG_IMG) {
@ -107,6 +135,7 @@ public class TypeFace {
e.printStackTrace(); e.printStackTrace();
} }
} }
//System.out.println("Found light pixel");
} }
}break; }break;
case 2:{ case 2:{
@ -118,8 +147,17 @@ public class TypeFace {
X=img.getWidth(); X=img.getWidth();
break; break;
} else { } else {
X+=i.maxX-1;
numberImg = i.createImage(); numberImg = i.createImage();
if (numberImg.getWidth()>=32) {
state=0;
break;
}
X+=i.maxX;
if (numberImg.getHeight()<10 || numberImg.getWidth()<2) {
//A number should be at least 10 pixels high...This is not satisfactory.
state=4;
break;
}
//X+=numberImg.getWidth(); //X+=numberImg.getWidth();
state=3; state=3;
if (DEBUG_IMG) { if (DEBUG_IMG) {
@ -131,6 +169,7 @@ public class TypeFace {
e.printStackTrace(); e.printStackTrace();
} }
} }
//System.out.println("Moving to next step: ");
} }
}break; }break;
case 3:{ case 3:{
@ -140,6 +179,7 @@ public class TypeFace {
int[] hits = new int[NUMBER_COUNT]; int[] hits = new int[NUMBER_COUNT];
double highestRatio = 0; double highestRatio = 0;
int highest = 0; int highest = 0;
boolean goNext=false;
for (int k=0;k<NUMBER_COUNT;k++) { for (int k=0;k<NUMBER_COUNT;k++) {
BufferedImage img2 = ImageUtils.toCompatibleImage(ImageUtils.copyBufferedImage(numberImg)); BufferedImage img2 = ImageUtils.toCompatibleImage(ImageUtils.copyBufferedImage(numberImg));
for (int i=0;i<WIDTH;i++) { for (int i=0;i<WIDTH;i++) {
@ -147,8 +187,23 @@ public class TypeFace {
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].getGreen()==pixel.getGreen() && numbers[i*HEIGHT+j][k].getBlue()==pixel.getBlue()) { if (numbers[i*HEIGHT+j][k].getRed()==0 && numbers[i*HEIGHT+j][k].getGreen()==255 && numbers[i*HEIGHT+j][k].getBlue()==0
&& pixel.getRed()==255 && pixel.getGreen()==255 && pixel.getBlue()==255) {
goNext=true;
img2.setRGB(i, j, Color.MAGENTA.getRGB());
break;
}
if (numbers[i*HEIGHT+j][k].getRed()==255 && numbers[i*HEIGHT+j][k].getGreen()==0 && numbers[i*HEIGHT+j][k].getBlue()==0
&& pixel.getRed()==0 && pixel.getGreen()==0 && pixel.getBlue()==0) {
goNext=true;
img2.setRGB(i, j, Color.YELLOW.getRGB());
break;
}
if (numbers[i*HEIGHT+j][k].equals(Color.RED) || numbers[i*HEIGHT+j][k].equals(Color.GREEN) ||
(numbers[i*HEIGHT+j][k].getRed()==pixel.getRed() && numbers[i*HEIGHT+j][k].getGreen()==pixel.getGreen() && numbers[i*HEIGHT+j][k].getBlue()==pixel.getBlue())) {
if (!(numbers[i*HEIGHT+j][k].equals(Color.GREEN) && numbers[i*HEIGHT+j][k].equals(Color.RED))) {
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);
@ -164,6 +219,7 @@ public class TypeFace {
} }
} }
} }
if (goNext) {break;}
} }
FileUtils.logToFile(((k+1)%NUMBER_COUNT)+":"+((double)(hits[k])/(WIDTH*HEIGHT)), 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 {
@ -171,6 +227,7 @@ public class TypeFace {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
goNext=false;
} }
//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++; iterations++;
@ -178,11 +235,9 @@ public class TypeFace {
state=4; state=4;
}break; }break;
case 4:{ case 4:{
//Find dark pixels again. //Find light pixels again.
if (p.getBlue()>blue_minthreshold && p.getBlue()<blue_maxthreshold && if (p.getBlue()>200 && p.getGreen()>200 && p.getRed()>200) {
p.getGreen()>green_minthreshold && p.getGreen()<green_maxthreshold && X-=2;
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) {
//We found a dark pixel. Back to the start.
state=0; state=0;
if (DEBUG_IMG) { if (DEBUG_IMG) {
try { try {
@ -193,6 +248,7 @@ public class TypeFace {
e.printStackTrace(); e.printStackTrace();
} }
} }
//System.out.println("Found next dark pixel");
} }
}break; }break;
} }

View File

@ -1 +1,7 @@
# Charset of HTTP requests and responses. Added to the "Content-Type" header if not set explicitly.
spring.http.encoding.charset=UTF-8
# Enable http encoding support.
spring.http.encoding.enabled=true
# Force the encoding to the configured charset on HTTP requests and responses.
spring.http.encoding.force=true

BIN
temp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 208 KiB

View File

@ -1,10 +1,10 @@
1:0.591796875 1:0.505859375
2:0.880859375 2:0.005859375
3:0.818359375 3:0.005859375
4:0.486328125 4:0.84765625
5:0.751953125 5:0.2333984375
6:0.806640625 6:0.048828125
7:0.501953125 7:0.001953125
8:0.81640625 8:0.048828125
9:0.76953125 9:0.2197265625
0:0.681640625 0:0.06640625

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 B

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 B

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 B

After

Width:  |  Height:  |  Size: 150 B

View File

@ -1,10 +1,10 @@
1:0.75 1:0.80078125
2:0.83203125 2:0.0078125
3:0.85546875 3:0.00390625
4:0.609375 4:0.044921875
5:0.8359375 5:0.73828125
6:0.87890625 6:0.068359375
7:0.578125 7:0.00390625
8:0.947265625 8:0.068359375
9:0.900390625 9:0.822265625
0:0.80859375 0:0.09375

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 B

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

After

Width:  |  Height:  |  Size: 140 B

View File

@ -1,10 +1,10 @@
1:0.626953125 1:0.751953125
2:0.927734375 2:0.068359375
3:0.853515625 3:0.9765625
4:0.521484375 4:0.037109375
5:0.740234375 5:0.0810546875
6:0.806640625 6:0.056640625
7:0.548828125 7:0.0078125
8:0.8515625 8:0.05078125
9:0.8046875 9:0.052734375
0:0.716796875 0:0.072265625

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 B

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 B

After

Width:  |  Height:  |  Size: 136 B

BIN
tmp/cool/img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

View File

@ -1,10 +1,10 @@
1:0.6328125 1:0.46484375
2:0.72265625 2:0.03515625
3:0.88671875 3:0.169921875
4:0.65625 4:0.037109375
5:0.953125 5:0.0517578125
6:0.890625 6:0.0234375
7:0.6015625 7:0.90234375
8:0.845703125 8:0.0234375
9:0.939453125 9:0.044921875
0:0.7109375 0:0.03125

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 B

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 B

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

After

Width:  |  Height:  |  Size: 118 B

View File

@ -1,10 +1,10 @@
1:0.75390625 1:0.748046875
2:0.83203125 2:0.0078125
3:0.8515625 3:0.00390625
4:0.60546875 4:0.04296875
5:0.83203125 5:0.861328125
6:0.875 6:0.064453125
7:0.57421875 7:0.00390625
8:0.943359375 8:0.064453125
9:0.896484375 9:0.677734375
0:0.80859375 0:0.08984375

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 131 B

Some files were not shown because too many files have changed in this diff Show More