Что нового

[Автоматизация] Утилита для написания кода AutoIt по распознованию цифр с экрана (не капчи)

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Мне в ботах часто приходится читать на экране цифры, которые расположены в фиксированном месте, на однотонном фоне и написаны нормальным шрифтом.
В память я не лезу и внешние программы тоже неохотно использую.
Поэтому я распознаю цифры в самих скриптах своих ботов.

История создания
Когда мне понадобилось распознавать цифры для ботов, я написал утилиту, в которую руками вбивал область поиска, и границы цвета, которыми написаны цифры. Эта утилита по нажатию HotKey записывала в лог-файл * и . для фиксации изображения цифры.
Потом я брал листочек, рисовал на нём клетки, соответствующие пикселям, и вписывал туда какая цифра отображается в этом пикселе. Ну а потом уже выбирал уникальные пиксели для каждой цифры...
А потом устал рисовать клеточки на листочке и вот.

Как пользоваться утилитой.
Само-собой, запустить. Она повиснет в трее.
После этого нужно определить область, в которой появляются цифры. Навести мышку на левый верхний угол этого прямоугольника и нажать Shift+Alt+b. Навести мышку на правый нижний угол этого прямоугольника и нажать Shift+Alt+e.
Затем нужно определить цвет фона, на котором рисуются цифры - навести мышку на "пустое" место и нажать Shift+Alt+f.
После этого, когда в игре будут отображаться цифры, зафиксировать изображение всех цифр - Shift+Alt+1 ... Shift+Alt+0
Когда всё это проделано нажать Shift+Alt+x
(Само собой можно поставить любые удобные комбинации кнопок)
Код:
#include <Color.au3>

HotKeySet("+!b", "_capture_zone_begin")  ;Shift+Alt+b
HotKeySet("+!e", "_capture_zone_end")  ;Shift+Alt+e
HotKeySet("+!f", "_capture_fone")  ;Shift+Alt+f
HotKeySet("+!0", "_capture_0")  ;Shift+Alt+0
HotKeySet("+!1", "_capture_1")  ;Shift+Alt+1
HotKeySet("+!2", "_capture_2")  ;Shift+Alt+2
HotKeySet("+!3", "_capture_3")  ;Shift+Alt+3
HotKeySet("+!4", "_capture_4")  ;Shift+Alt+4
HotKeySet("+!5", "_capture_5")  ;Shift+Alt+5
HotKeySet("+!6", "_capture_6")  ;Shift+Alt+6
HotKeySet("+!7", "_capture_7")  ;Shift+Alt+7
HotKeySet("+!8", "_capture_8")  ;Shift+Alt+8
HotKeySet("+!9", "_capture_9")  ;Shift+Alt+9
HotKeySet("+!x", "_calculate")  ;Shift+Alt+x

Global $X_left, $X_right, $Y_up, $Y_down, $fone_color
Global $left_up_flag = False, $right_down_flag = False, $fone_flag = False, $array_flag = False

$file = FileOpen("capture.log", 1)

While 1
	Sleep(1000)
	If $left_up_flag And $right_down_flag And Not $array_flag Then	; если определён верхний левый угол, определён правый нижний угол и матрица цифр ещё не создана
		Dim $matrix[$X_right - $X_left +1][$Y_down - $Y_up +1]		; создаём матрицу цифр
		$array_flag = True											; и отмечаем что она уже создана
		FileWriteLine($file,"Зона распознавания цифр")
		FileWriteLine($file,"X: "& $X_left & "-" & $X_right)
		FileWriteLine($file,"Y: "& $Y_up & "-" & $Y_down)
		FileWriteLine($file,"")
	EndIf
WEnd

FileClose($file)

Func _capture_zone_begin()		; определение верхнего левого угла зоны появления цифр
	Local $pos = MouseGetPos()
	$X_left = $pos[0]
	$Y_up = $pos[1]
	$left_up_flag = True
	ToolTip("левый верхний угол определён",0,0)
EndFunc

Func _capture_zone_end()		; определение правого нижнего угла зоны появления цифр
	Local $pos = MouseGetPos()
	$X_right = $pos[0]
	$Y_down = $pos[1]
	$right_down_flag = True
	ToolTip("правый нижний угол определён",0,0)
EndFunc

Func _capture_fone()			; определение цвета фона
	Local $pos = MouseGetPos()
	$fone_color = PixelGetColor($pos[0],$pos[1])
	$fone_flag = True
	ToolTip("цвет фона " & Hex($fone_color),0,0)
EndFunc

Func _calculate()				; ГЛАВНОЕ
	FileClose($file)							; закрываем файл логирования пикселей
	$code_file = FileOpen("capture.au3", 1)		; открываем файл написания кода функции для скрипта
	FileWriteLine($code_file, "Func _detect_digit()")

	Local $detected[10] = [False,False,False,False,False,False,False,False,False,False]	; отмечам что ни для одной цифры код ещё не написан

	For $perebor = 0 To 9						; 10 раз производим поиск пикселя который пренадлежит только одной цифре (ОСНОВНАЯ ИДЕЯ АЛГОРИТМА)
		For $digit = 0 To 9						; перебираем цифры от 0 до 9
			If Not $detected[$digit] Then		; если уникальный пиксель для этой цифры ещё не найден, то ищем его
				For $i = $X_left To $X_right	; перебираем все пиксели в зоне поиска цифр
					For $j = $Y_up to $Y_down	; перебираем все пиксели в зоне поиска цифр
						If $matrix[$i-$X_left][$j-$Y_up] == String($digit) Then ; если в матрице пикселей на этих координатах зафиксирована ТОЛЬКО ЭТА ЦИФРА, то ура
							FileWriteLine($file, "   If PixelGetColor(" & $i & "," & $j & ") <> 0x" & StringTrimLeft(Hex($fone_color),2) & " Then Return " & $digit)
							$detected[$digit] = True	; отмечаем что распознавание этой цифры сделано
							_remove_digit($digit)		; и удаляем эту цифру из матрицы пикселей
							ExitLoop 2
						EndIf
					Next
				Next
			EndIf
		Next
	Next

	For $i = 0 To 9				; если для какой-то цифры уникальные пиксели не найдены, то информируем об этом
		If Not $detected[$i] Then
			FileWriteLine($code_file, "; не удалось обнаружить уникальные пиксели для цифры " & $i & ". Для анализа смотрите лог.")
		EndIf
	Next

	FileWriteLine($code_file, "EndFunc")
	FileClose($code_file)
	Exit
EndFunc

Func _capture_0()
	_capture_main(0)
EndFunc

Func _capture_1()
	_capture_main(1)
EndFunc

Func _capture_2()
	_capture_main(2)
EndFunc

Func _capture_3()
	_capture_main(3)
EndFunc

Func _capture_4()
	_capture_main(4)
EndFunc

Func _capture_5()
	_capture_main(5)
EndFunc

Func _capture_6()
	_capture_main(6)
EndFunc

Func _capture_7()
	_capture_main(7)
EndFunc

Func _capture_8()
	_capture_main(8)
EndFunc

Func _capture_9()
	_capture_main(9)
EndFunc

Func _capture_main($number)					; обработка изображения цифры
	FileWriteLine($file,"Mask " & $number)
	For $j = $Y_up To $Y_down
		For $i = $X_left To $X_right		; перебираем все пиксели в зоне поиска цифр
			$color = PixelGetColor($i,$j)	; перебираем все пиксели в зоне поиска цифр
			If $color <> $fone_color Then	; ЕСЛИ ЦВЕТ ПИКСЕЛЯ ОТЛИЧАЕТСЯ ОТ ЦВЕТА ФОНА, то фиксируем эту цифру в матрице пикселей
				If StringInStr($matrix[$i-$X_left][$j-$Y_up],String($number)) = 0 Then $matrix[$i-$X_left][$j-$Y_up] &= $number
				FileWrite($file, "*")		; в логе отмечаем что на этих координатах не пусто
			Else
				FileWrite($file, ".")		; а если тут цвет фона, то в логе отмечаем что клетка пустая
			EndIf
		Next
		FileWriteLine($file,"")
	Next
	FileWriteLine($file,"")
	ToolTip("обработано " & $number,0,0)
EndFunc

Func _remove_digit($number)			; удаляем в матрице пикселей все упоминаний об указанной цифре
	For $i = 0 To $X_right - $X_left	; перебираем все пиксели в зоне поиска цифр
		For $j = 0 To $Y_down - $Y_up	; перебираем все пиксели в зоне поиска цифр
			$matrix[$i][$j] = StringReplace($matrix[$i][$j], String($number), "") ; вычёркиваем эту цифру
		Next
	Next
EndFunc

После завершения скрипта, в том каталоге откуда он был запущен, появятся два файла:
.au3 -код функции для распознавания цифр
.log - собственно лог захвата изображений

GUI не рисовал так как игрушки у меня в полноэкранном режиме.
Та и типсы от отладки остались. :smile:
 

Andrei7

Новичок
Сообщения
72
Репутация
3
можете привести в пример парочку таких игр, где такое нужно? :smile:
 
Автор
C2H5OH

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Во, вспомнил игру, где администрация уходит от рассмотрения вопросов о легальности использования такого вида ботов, то есть закрывает глаза. (а так вообще вопрос нетактичный...)

Правда там фон не однотонный, поэтому я для этой игры в зоне появления цифр искал пиксели у которых красная составляющая больше 200 (белое на синем фоне :smile:) А так алгоритм тот же.
 

_ToBe_

Осваивающий
Сообщения
142
Репутация
35
А сколько времени занимает анализ строки с 10-ти значным значением?
 
Автор
C2H5OH

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
10 запусков - по одному на каждый знак (вообще-то в таком случае у меня был бы один запуск на одну позицию, а потом рассчет смещения для каждого разряда).

_ToBe_,
ты не понял суть алгоритмя. Берется место где появляется одна цифра. Собираются пиксели всех цифр от 1 до 0, когда они появляются в этом месте. А потом определяются пиксели, которые принадлежат только одной из этих цифр.
Дальше строится функция, которая по анализу появления этих пикселей определяет какая там цифра.
 

Дмитрий1984

Новичок
Сообщения
24
Репутация
0
C2H5OH сказал(а):
_ToBe_,
ты не понял суть алгоритмя. Берется место где появляется одна цифра. Собираются пиксели всех цифр от 1 до 0, когда они появляются в этом месте. А потом определяются пиксели, которые принадлежат только одной из этих цифр.
Дальше строится функция, которая по анализу появления этих пикселей определяет какая там цифра.

Ты бы мог написать эту функцию? Во флэш в определенной области цифры. Координаты могут незначительно смещаться, но есть область, где они точно находятся. Как их конвертировать в цифровое значение. Очень прошу код.
 
Автор
C2H5OH

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Re: [Данные, строки] Распознавание текста

Дмитрий1984,
angrypets - это браузерка в чистом виде. Никаким флешем там и не пахнет. Не морочь голову себе и другим надуманным распознаванием текста. Твоё золото находится здесь.

Код:
<span title="золото" class="gold"><i></i>0</span>
 

Дмитрий1984

Новичок
Сообщения
24
Репутация
0
Re: [Данные, строки] Распознавание текста

C2H5OH сказал(а):
Дмитрий1984,
angrypets - это браузерка в чистом виде. Никаким флешем там и не пахнет. Не морочь голову себе и другим надуманным распознаванием текста. Твоё золото находится здесь.

Код:
<span title="золото" class="gold"><i></i>0</span>

И что дальше? Я не про angrypets.
 
Автор
C2H5OH

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
[Автоматизация] Утилита для написания кода AutoIt по распознованию цифр с экрана

Ты приводишь скриншот из angrypets, где число написано непропорциональным шрифтом. Та утилита которую я предлагал, работает с пропорциональными шрифтами.
Даже не знаю что дальше...
 

Дмитрий1984

Новичок
Сообщения
24
Репутация
0
C2H5OH сказал(а):
Ты приводишь скриншот из angrypets, где число написано непропорциональным шрифтом. Та утилита которую я предлагал, работает с пропорциональными шрифтами.
Даже не знаю что дальше...

Вот что распознать нужно(шрифт мелкий и на границе может быть легкое перетекание в фон):

a2de0-clip-3kb.jpg
 
Верх