Что нового

Цвет пикселя

hiho

Новичок
Сообщения
16
Репутация
2
Добрый день. Возникла необходимость определять цвет пикселя не стандартным способом, а точнее - определить к какому из 4 цветов(красный, зелёный, желтый, белый) "ближе" цвет пикселя. Задача стоит не столько в написании на конкретном языке, а в самом алгоритме, можно ли заставить программу "визуально" отличать цвета?
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
Все зависит от того, что Вы подразумеваете под "ближе".
А так, один из вариантов: преобразовываете в 16-ричный код формата RGB и для каждой цветовой составляющей определяете разницу.
 
Автор
H

hiho

Новичок
Сообщения
16
Репутация
2
Дело в том, что именно так и делал, но программа иногда ошибалась, то есть RGB составляющие цвета меняются постоянно, что не позволяет получить своеобразную константу, на которую цвет будет отличаться от того или иного. Вот и думаю над более точным алгоритмом
 

WSWR

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

Вот функция сравнения цветов с оф форума:
Код:
ConsoleWrite('Color difference: ' & _Color_ColorDifference(0x8F1EFF00, 0x6700CC00) & @CRLF)

; #FUNCTION# ===================================================================
; Name ..........: _Color_ColorDifference
; Description ...: Calculate difference between two colors.
; Syntax ........: _Color_ColorDifference($vARGB1, $vARGB2)
; Parameters ....: $vARGB1 - Variant: A Hex, Integer or Binary color value.
;                  $vARGB2 - Variant: A Hex, Integer or Binary color value.
; Return values .: Success - Int: Color difference.
;                  Failure - Int: Returns 0 and sets @error:
;                  |1 First parameter isn't a Hex string.
;                  |2 Second parameter isn't a Hex string.
; Author ........: dany
; Modified ......:
; Remarks .......: A value of 500 or higher is recommended for good contrast.
; Link ..........: http://www.w3.org/TR/2000/WD-AERT-20000426#color-contrast
; ==============================================================================
Func _Color_ColorDifference($vARGB1, $vARGB2)
	If IsInt($vARGB1) Or IsBinary($vARGB1) Then $vARGB1 = Hex($vARGB1)
	If IsInt($vARGB2) Or IsBinary($vARGB1) Then $vARGB2 = Hex($vARGB2)
	If Not StringIsXDigit($vARGB1) Then Return SetError(1, 0, 0)
	If Not StringIsXDigit($vARGB2) Then Return SetError(2, 0, 0)
	If 7 > StringLen($vARGB1) Then $vARGB1 = 'FF' & $vARGB1
	If 7 > StringLen($vARGB2) Then $vARGB1 = 'FF' & $vARGB2
	Local $iRed, $iGreen, $iBlue, $iColor1, $iColor2
	$iColor1 = Dec(StringMid($vARGB1, 3, 2))
	$iColor2 = Dec(StringMid($vARGB2, 3, 2))
	$iRed = __Color_Max($iColor1, $iColor2) - __Color_Min($iColor1, $iColor2)
	$iColor1 = Dec(StringMid($vARGB1, 5, 2))
	$iColor2 = Dec(StringMid($vARGB2, 5, 2))
	$iGreen = __Color_Max($iColor1, $iColor2) - __Color_Min($iColor1, $iColor2)
	$iColor1 = Dec(StringMid($vARGB1, 7, 2))
	$iColor2 = Dec(StringMid($vARGB2, 7, 2))
	$iBlue = __Color_Max($iColor1, $iColor2) - __Color_Min($iColor1, $iColor2)
	Return $iRed + $iGreen + $iBlue
EndFunc   ;==>_Color_ColorDifference

; #INTERNAL_USE_ONLY# ==========================================================
; Name ..........: __Color_Min
; Description ...: Return lowest of two values.
; Remarks .......: For Internal Use Only.
; ==============================================================================
Func __Color_Min($iX, $iY)
	If Number($iX) > Number($iY) Then Return $iY
	Return $iX
EndFunc   ;==>__Color_Min

; #INTERNAL_USE_ONLY# ==========================================================
; Name ..........: __Color_Max
; Description ...: Return highest of two values.
; Remarks .......: For Internal Use Only.
; ==============================================================================
Func __Color_Max($iX, $iY)
	If Number($iX) < Number($iY) Then Return $iY
	Return $iX
EndFunc   ;==>__Color_Max

Сравнить имеющийся цвет с помощью этой функции с красным, зелёным, желтым, белым, где разница меньше - к тому и ближе.
 
Автор
H

hiho

Новичок
Сообщения
16
Репутация
2
_Color_ColorDifference(0xA1DB66, 0xFFFFFF) = 283
_Color_ColorDifference(0xA1DB66, 0xFF00FF) = 299
Тестируемый цвет: Белый

Один из вариантов вот этой формулы всё равно ошибается ::smile: Вики
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
hiho
Функция перевода из RGB в LAB (правда, не уверен, что правильно)
и сравнение как в простейшем примере из википедии:

Код:
#include <Color.au3>

ConsoleWrite(_ColorDifference(0xFFFFFF, 0xA1DB66) & @CRLF)
ConsoleWrite(_ColorDifference(0xFF00FF, 0xA1DB66) & @CRLF)

Func _ColorDifference($nColor1, $nColor2)
	$aColor1 = _RGB_LAB($nColor1)
	$aColor2 = _RGB_LAB($nColor2)
	$idE = Sqrt(($aColor1[0] - $aColor2[0]) ^ 2 + ($aColor1[1] - $aColor2[1]) ^ 2 + ($aColor1[2] - $aColor2[2]) ^ 2)
	Return $idE
EndFunc   ;==>_ColorDifference

Func _RGB_LAB($nColor)
	$m_R = _ColorGetRed($nColor)
	$m_G = _ColorGetGreen($nColor)
	$m_B = _ColorGetBlue($nColor)
	
	$t_rf = $m_R / 255.0
	$t_gf = $m_G / 255.0
	$t_bf = $m_B / 255.0

	If($t_rf > 0.04045) Then
		$t_rf = Exp((Log(($t_rf + 0.055) / 1.055) * 2.4))
	Else
		$t_rf = $t_rf / 12.92
	EndIf

	If($t_gf > 0.04045) Then
		$t_gf = Exp((Log(($t_gf + 0.055) / 1.055) * 2.4))
	Else
		$t_gf = $t_gf / 12.92
	EndIf

	If($t_bf > 0.04045) Then
		$t_bf = Exp((Log(($t_bf + 0.055) / 1.055) * 2.4))
	Else
		$t_bf = $t_bf / 12.92
	EndIf

	$t_X = 0.412453 * $t_rf + 0.357580 * $t_gf + 0.180423 * $t_bf
	$t_Y = 0.212671 * $t_rf + 0.715160 * $t_gf + 0.072169 * $t_bf
	$t_Z = (0.019334 * $t_rf + 0.119193 * $t_gf + 0.950227 * $t_bf) * 0.918483657

	If($t_X > 0.008856) Then
		$t_fX = Exp(Log($t_X) / 3.0)
	Else
		$t_fX = ((7.787 * $t_X) + (16.0 / 116.0))
	EndIf
	
	If($t_Y > 0.008856) Then
		$t_fY = Exp(Log($t_Y) / 3.0)
	else
		$t_fY = ((7.787 * $t_Y) + (16.0 / 116.0))
	EndIf
	
	If($t_Z > 0.008856) Then
		$t_fZ = Exp(Log($t_Z) / 3.0)
	Else
		$t_fZ = ((7.787 * $t_Z) + (16.0 / 116.0))
	EndIf

	$m_L = ((116.0 * $t_fY) - 16.0)
	$m_a = (500.0 * ($t_fX - $t_fY))
	$m_B = (200.0 * ($t_fY - $t_fZ))

	Dim $alab[3]
	
	$alab[0] = $m_L
	$alab[1] = $m_a
	$alab[2] = $m_B
	
	Return $alab

EndFunc   ;==>_RGB_LAB
 
Автор
H

hiho

Новичок
Сообщения
16
Репутация
2
Действительно, забыл про перевод в LAB, спасибо огромное, сегодня буду тестировать
 
Верх