自动识别CFM比分截图
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); | |
class Recognize_Score_Model extends CI_Model | |
{ | |
private $phashCacheDir; | |
private $phashMap = array(); | |
protected $imgMap = array( | |
'1334x750' => array( | |
'score' => array( | |
'left' => array(468, 87, 66, 35), | |
'right' => array(797, 87, 66, 35) | |
), | |
'players' => array( | |
'left' => array( | |
array( | |
'name' => array(208, 176, 188, 27), | |
'score' => array(353, 203, 90, 27) | |
), | |
array( | |
'name' => array(208, 268, 188, 27), | |
'score' => array(353, 295, 90, 27) | |
), | |
array( | |
'name' => array(208, 360, 188, 27), | |
'score' => array(353, 387, 90, 27) | |
), | |
array( | |
'name' => array(208, 453, 188, 27), | |
'score' => array(353, 480, 90, 27) | |
), | |
array( | |
'name' => array(208, 547, 188, 27), | |
'score' => array(353, 574, 90, 27) | |
) | |
), | |
'right' => array( | |
array( | |
'name' => array(771, 176, 188, 27), | |
'score' => array(920, 203, 90, 27) | |
), | |
array( | |
'name' => array(771, 268, 188, 27), | |
'score' => array(920, 295, 90, 27) | |
), | |
array( | |
'name' => array(771, 360, 188, 27), | |
'score' => array(920, 387, 90, 27) | |
), | |
array( | |
'name' => array(771, 453, 188, 27), | |
'score' => array(920, 480, 90, 27) | |
), | |
array( | |
'name' => array(771, 547, 188, 27), | |
'score' => array(920, 574, 90, 27) | |
) | |
) | |
) | |
) | |
); | |
function __construct() | |
{ | |
$this->load->library('TesseractOCR'); | |
} | |
/** | |
* 识别CFM比分截图 | |
* @param [string] $image 截图本地存储地址 | |
* @return [array] 比分结果 | |
*/ | |
function recognize($image) | |
{ | |
$pathinfo = pathinfo($image); | |
$image = imagecreatefrompng($image); | |
$width = imagesx($image); | |
$height = imagesy($image); | |
$dem = $width . 'x' . $height; | |
$result = array(); | |
// 获取不到对应尺寸的位置信息 | |
if (!isset($this->imgMap[$dem])) { | |
return $result; | |
} | |
$imgMap = $this->imgMap[$dem]; | |
// 识别并获取总比分 | |
foreach ($imgMap['score'] as $team => $rect) { | |
$dest = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '_' . $team . '.' . $pathinfo['extension']; | |
$this->crop($image, $rect, $dest); | |
$result[$team] = array(); | |
$result[$team]['total'] = (new TesseractOCR($dest))->lang('cf')->whitelist(range(0, 9))->psm(8)->run(); | |
// 删除切片 | |
unlink($dest); | |
} | |
foreach ($imgMap['players'] as $team => $players) { | |
$result[$team]['players'] = array(); | |
foreach ($players as $i => $player) { | |
// 识别名字 | |
$dest = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '_' . $team . '_' . $i . '_name' . '.' . $pathinfo['extension']; | |
$this->crop($image, $player['name'], $dest); | |
$name = (new TesseractOCR($dest))->lang('cf')->psm(8)->run(); | |
// 删除切片 | |
unlink($dest); | |
// 识别比分 | |
$dest = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '_' . $team . '_' . $i . '_score' . '.' . $pathinfo['extension']; | |
$this->crop($image, $player['score'], $dest); | |
$score = (new TesseractOCR($dest))->lang('cf')->whitelist(range(0, 9), '/')->psm(8)->run(); | |
// 删除切片 | |
unlink($dest); | |
// 提取比分 | |
if (!empty($score)) { | |
$score = explode('/', $score); | |
} else { | |
$score = array(); | |
} | |
$result[$team]['players'][] = array( | |
'name' => $name, | |
'kill' => isset($score[0]) ? $score[0] : '', | |
'die' => isset($score[1]) ? $score[1] : '' | |
); | |
} | |
} | |
return $result; | |
} | |
/** | |
* 按位置截取切片 | |
* @param [type] $src 原图 | |
* @param [type] $rect 截取区域 | |
* @param [type] $dest 切片保存位置 | |
* @return [type] [description] | |
*/ | |
function crop($src, $rect, $dest) { | |
$crop = imagecreatetruecolor($rect[2], $rect[3]); | |
imagecopy( | |
$crop, | |
$src, | |
0, | |
0, | |
$rect[0], | |
$rect[1], | |
$rect[2], | |
$rect[3] | |
); | |
// 将图片灰度化,反色化 | |
// $this->image_filter_invert($crop); | |
// $this->image_filter_grayscale($crop); | |
imagepng($crop, $dest); | |
imagedestroy($crop); | |
} | |
function image_filter_invert(&$image){ | |
$width = imagesx($image); | |
$height = imagesy($image); | |
for($x = 0; $x < $width; $x++){ | |
for($y = 0; $y < $height; $y++){ | |
$rgb = imagecolorat($image, $x, $y); | |
$r = 0xFF-(($rgb>>16)&0xFF); | |
$g = 0xFF-(($rgb>>8)&0xFF); | |
$b = 0xFF-($rgb&0xFF); | |
$color = imagecolorallocate($image, $r, $g, $b); | |
imagesetpixel($image, $x, $y, $color); | |
} | |
} | |
} | |
function image_filter_grayscale(&$image){ | |
$width = imagesx($image); | |
$height = imagesy($image); | |
for($x = 0; $x < $width; $x++){ | |
for($y = 0; $y < $height; $y++){ | |
$rgb = imagecolorat($image, $x, $y); | |
$r = ($rgb>>16)&0xFF; | |
$g = ($rgb>>8)&0xFF; | |
$b = $rgb&0xFF; | |
$bw = (int)(($r+$g+$b)/3); | |
$color = imagecolorallocate($image, $bw, $bw, $bw); | |
imagesetpixel($image, $x, $y, $color); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment