Что нового

Сравнение картинок и удаление одинаковых.

kolosov

Новичок
Сообщения
137
Репутация
0
Ребят. Можно по системе autoit сравнить картинки?
К примеру если в папке есть 2 одинаковых картинки, но у них разные названия,
можно что-то сделать чтобы скрипт понял что они одинаковы и удолил ту у которой разришение меньше.То Есть не по разрешению смотрел! А именно к примеру сравнивал каждый пиксель и как только пиксели у картинки отличаться скрипт шел дальше.
Зарание спасибо. И если возможно не большой пример.
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
Re: Сравнение.

Каждый пиксель, это как раз с разным разрешением картинки будут разные.
Вам, как я понимаю, нужно эскизы сравнивать.
 
Автор
K

kolosov

Новичок
Сообщения
137
Репутация
0
Может и так. В общем чтобы скрипт сравнивал картинки и если они одинаковые то одну удолял.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
kolosov
Сравниваете пропорции 4x10 пропорционально 8x20, хотя размер разный, а вот 4x10 и 4x15 пропорции явно разные. Можно задать небольшую позволительность в пропорциях к примеру не более 2%. Если пропорции не совпадают и файлы разные, а если совпадают, то привести к одному размеру, наверно лучше к меньшему, так как меньший к больший явно не сгенерирует новые пиксели. Ну и сравнить миниатюры методом вычитания цветов, далее разницу суммировать в некий усреднённый показатель, например сложить все разницы и разделить на количество разниц. Получим среднюю разницу. Потом задать допустимый показатель разницы, например если разница более 2%, то считать их разными.
Можно сделать гистограмму, то есть определить количество цветов, которые превысили порог 2%, определить количество цветов, которые превысили 30%, и т.д. А дальше тестами вычислить визуальное восприятие с числовыми показателями.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
kolosov

Вариант:
Код:
#include <File.au3>
#include <Array.au3>
#include <GDIPlus.au3>

$aFileList = _FileListToArray(@ScriptDir, '*.jpg', 1)
$sResult = ''
$step = 50 ; шаг при получении массива пикселей, чем больше - тем быстрее работает скрипт
$iN = 10 ; количество наиболее часто встречающихся цветов в массиве, которое берется с начала массива
$iR = 50 ; % совпадения картинок, для отбора на удаление

Dim $aResult[$aFileList[0] + 1][4]

$aResult[0][0] = $aFileList[0]

For $i = 1 To $aFileList[0]
	$avArray = _fon($aFileList[$i], $step, $iN)
	$sTring = ''
	For $j = 1 To $iN
		$sTring &= $avArray[$j][0] & '|'
	Next

	$sTring = StringTrimRight($sTring, 1)
	$aResult[$i][0] = $aFileList[$i]
	$aResult[$i][2] = $avArray[0][0]
	$aResult[$i][3] = $sTring
	$sResult &= $sTring & '%'
Next

$sResult = StringTrimRight($sResult, 1)

For $i = 1 To $aResult[0][0]
	$sResult1 = StringRegExpReplace($sResult, $aResult[$i][3], '*')

	$aSplit = StringSplit($sResult1, '%')

	For $j = 1 To $aSplit[0]
		If $j <> $i Then
			StringReplace($aSplit[$j], '*', '')
			$iT = (@extended / $iN * 100)
			$aSplit[$j] = $aResult[$j][0] & '      ' & $iT & ' %'
			If $iT >= $iR And $aResult[$i][2] > $aResult[$j][2] Then $aResult[$j][1] = 'DEL'
		Else
			$aSplit[$j] = ''
		EndIf
	Next
	$aSplit[0] = $aResult[$i][0]
	_ArrayDisplay($aSplit) ; отображение соотоношения "похожести" картинок, в 0-м элементе - картинка, с которой сравниваются остальные
Next

ReDim $aResult[$aResult[0][0] + 1][2]

_ArrayDisplay($aResult) ; отображение списка картинок, "DEL" - картинки, помеченные для удаления


Func _fon($sPath, $iStep, $iCount)
	Local $hBitmap, $tMap, $Width, $Height, $bData, $i, $aTemp
	_GDIPlus_Startup()
	$hBitmap = _GDIPlus_BitmapCreateFromFile($sPath)
	$Width = _GDIPlus_ImageGetWidth($hBitmap)
	$Height = _GDIPlus_ImageGetHeight($hBitmap)
	$tMap = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Width, $Height, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
	$bData = DllStructGetData(DllStructCreate('byte[' & ($Width * $Height * 4) & ']', DllStructGetData($tMap, 'Scan0')), 1)
	_GDIPlus_BitmapUnlockBits($hBitmap, $tMap)
	_GDIPlus_BitmapDispose($hBitmap)
	_GDIPlus_Shutdown()
	$bData = StringTrimLeft($bData, 2)
	$bData = '######FF' & $bData

	$aTemp = StringRegExp($bData, '(\S{1,30})FF', 3)
	_ArrayTrim($aTemp, 24, 1)
	$aTemp[0] = UBound($aTemp) - 1

	For $i = 1 To $aTemp[0] Step $iStep
		Assign($aTemp[$i], Eval($aTemp[$i]) + 1)
	Next

	Dim $uArray[$aTemp[0]][2] = [[0]]

	For $i = 1 To $aTemp[0] Step $iStep
		If Eval($aTemp[$i]) > 0 Then
			$uArray[0][0] += 1
			$uArray[$uArray[0][0]][0] = $aTemp[$i]
			$uArray[$uArray[0][0]][1] = Eval($aTemp[$i])
			Assign($aTemp[$i], -1)
		EndIf
	Next
	ReDim $uArray[$uArray[0][0] + 1][2]

	_ArraySort($uArray, 1, 1, 0, 1)

	ReDim $uArray[$iCount + 1][1]
	$uArray[0][0] = $Width * $Height

	Return $uArray

EndFunc   ;==>_fon

Ограничение - картинки должны примерно до 5500х5500
И памяти может пару гигов отъесть)
 
Автор
K

kolosov

Новичок
Сообщения
137
Репутация
0
картинки должны быть меньше 4000х4000 ?

Тоисть будет работать только если разришение картинок больше 4000х4000 ?
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
kolosov
Переделал скрипт, теперь может работать с картинками примерно до 5500х5500
 
Автор
K

kolosov

Новичок
Сообщения
137
Репутация
0
Что-то не могу понять как работает. Киданал в папку 4 картинки 2 одинаковых и 2 разных запускаю скрипт в этой папке поевляеться окошко итам пишит название картинок но не удоляет одну котороя повторяется
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
kolosov
Да, он не удаляет, а сравнивает и показывает, каке нужно удалить
Вот с удалением:
Код:
#include <File.au3>
#include <Array.au3>
#include <GDIPlus.au3>

$aFileList = _FileListToArray(@ScriptDir, '*.jpg', 1)
$sResult = ''
$step = 50 ; шаг при получении массива пикселей, чем больше - тем быстрее работает скрипт
$iN = 10 ; количество наиболее часто встречающихся цветов в массиве, которое берется с начала массива
$iR = 40 ; % совпадения картинок, для отбора на удаление

Dim $aResult[$aFileList[0] + 1][4]

$aResult[0][0] = $aFileList[0]

For $i = 1 To $aFileList[0]
	$avArray = _fon($aFileList[$i], $step, $iN)
	$sTring = ''
	For $j = 1 To $iN
		$sTring &= $avArray[$j][0] & '|'
	Next

	$sTring = StringTrimRight($sTring, 1)
	$aResult[$i][0] = $aFileList[$i]
	$aResult[$i][2] = $avArray[0][0]
	$aResult[$i][3] = $sTring
	$sResult &= $sTring & '%'
Next

$sResult = StringTrimRight($sResult, 1)

For $i = 1 To $aResult[0][0]
	$sResult1 = StringRegExpReplace($sResult, $aResult[$i][3], '*')

	$aSplit = StringSplit($sResult1, '%')

	For $j = 1 To $aSplit[0]
		If $j <> $i Then
			StringReplace($aSplit[$j], '*', '')
			$iT = (@extended / $iN * 100)
			$aSplit[$j] = $aResult[$j][0] & '      ' & $iT & ' %'
			If $iT >= $iR And $aResult[$i][2] > $aResult[$j][2] Then $aResult[$j][1] = 'DEL'
		Else
			$aSplit[$j] = ''
		EndIf
	Next
	;$aSplit[0] = $aResult[$i][0]
	;_ArrayDisplay($aSplit) ; отображение соотоношения "похожести" картинок, в 0-м элементе - картинка, с которой сравниваются остальные
Next

ReDim $aResult[$aResult[0][0] + 1][2]

;_ArrayDisplay($aResult) ; отображение списка картинок, "DEL" - картинки, помеченные для удаления

For $i = 1 To $aResult[0][0]
	If $aResult[$i][1] = 'DEL' Then FileDelete($aResult[$i][0])
Next



Func _fon($sPath, $iStep, $iCount)
	Local $hBitmap, $tMap, $Width, $Height, $bData, $i, $aTemp
	_GDIPlus_Startup()
	$hBitmap = _GDIPlus_BitmapCreateFromFile($sPath)
	$Width = _GDIPlus_ImageGetWidth($hBitmap)
	$Height = _GDIPlus_ImageGetHeight($hBitmap)
	$tMap = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Width, $Height, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
	$bData = DllStructGetData(DllStructCreate('byte[' & ($Width * $Height * 4) & ']', DllStructGetData($tMap, 'Scan0')), 1)
	_GDIPlus_BitmapUnlockBits($hBitmap, $tMap)
	_GDIPlus_BitmapDispose($hBitmap)
	_GDIPlus_Shutdown()
	$bData = StringTrimLeft($bData, 2)
	$bData = '######FF' & $bData

	$aTemp = StringRegExp($bData, '(\S{1,30})FF', 3)
	_ArrayTrim($aTemp, 24, 1)
	$aTemp[0] = UBound($aTemp) - 1

	For $i = 1 To $aTemp[0] Step $iStep
		Assign($aTemp[$i], Eval($aTemp[$i]) + 1)
	Next

	Dim $uArray[$aTemp[0]][2] = [[0]]

	For $i = 1 To $aTemp[0] Step $iStep
		If Eval($aTemp[$i]) > 0 Then
			$uArray[0][0] += 1
			$uArray[$uArray[0][0]][0] = $aTemp[$i]
			$uArray[$uArray[0][0]][1] = Eval($aTemp[$i])
			Assign($aTemp[$i], -1)
		EndIf
	Next
	ReDim $uArray[$uArray[0][0] + 1][2]

	_ArraySort($uArray, 1, 1, 0, 1)

	ReDim $uArray[$iCount + 1][1]
	$uArray[0][0] = $Width * $Height

	Return $uArray

EndFunc   ;==>_fon
 
Автор
K

kolosov

Новичок
Сообщения
137
Репутация
0
Запустил скрипт. В папке было 4 картинки 2 одинаковые и 2 разные. И твой скрипт удолил одну ту котороя разная.
Одинаковые он не трогал (
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
У меня работает

Кто-нибудь, пожалуйста, протестируйте (нужно много памяти, если большие картинки)
 

MaximK

Знающий
Сообщения
33
Репутация
5
Не работает если к картинкам применить коррекцию (например автоуровень).
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
MaximK
Если это коррекция цветов, то, конечно, не работает.
Скрипт только для картинок, у которых разное разрешение - суть как раз в том, что у таких картинок наибольшую площадь занимают одни и те же цвета.


В принципе, можно написать и скрипт для визуального сравнения, но это уже другая тема.
 

ssvih-miaa

Новичок
Сообщения
41
Репутация
0
Re: Сравнение картинок и удаление одинаковых

Доброго времени суток!
Тема еще актуальна?
Попробовал скрипт с настройками
Код:
$step = 500 ; шаг при получении массива пикселей, чем больше - тем быстрее работает скрипт
$iN = 10 ; количество наиболее часто встречающихся цветов в массиве, которое берется с начала массива
$iR = 100 ; % совпадения картинок, для отбора на удаление


Находит одинаковые картинки но не удаляет, помогите разобраться.
Идея такая выдернуть картинку из браузера и сравнить её с картинками на сервере - в папке, и не удалить а просто определить 100% совпадение.
 
Верх