답변:
옵션 1 : 두 이미지를 모두 배열 ( scipy.misc.imread
) 로로드 하고 요소 별 (픽셀 별) 차이를 계산합니다. 차이의 규범을 계산하십시오.
옵션 2 : 두 이미지를 모두로드하십시오. 히스토그램과 같은 각각의 특징 벡터를 계산하십시오. 이미지가 아닌 특징 벡터 사이의 거리를 계산하십시오.
그러나 먼저 결정해야 할 사항이 있습니다.
먼저 다음 질문에 대답해야합니다.
모양과 치수가 같은 이미지입니까?
그렇지 않은 경우 크기를 조정하거나 잘라 내야 할 수도 있습니다. PIL 라이브러리는 파이썬에서 도움이 될 것입니다.
동일한 설정과 동일한 장치로 찍은 경우 아마도 동일 할 것입니다.
이미지가 잘 정렬되어 있습니까?
그렇지 않은 경우 먼저 가장 좋은 정렬을 찾기 위해 상호 상관을 실행하는 것이 좋습니다. SciPy는이를 수행하는 기능을 가지고 있습니다.
카메라와 장면이 여전히 맞으면 이미지가 잘 정렬 된 것입니다.
이미지 노출이 항상 동일합니까? (가벼움 / 대비가 동일합니까?)
그렇지 않은 경우 이미지 를 정규화 할 수 있습니다.
그러나 어떤 상황에서는 이것이 좋은 것보다 더 잘못 될 수 있으므로주의하십시오. 예를 들어, 어두운 배경에서 밝은 단일 픽셀은 정규화 된 이미지를 매우 다르게 만듭니다.
색상 정보가 중요합니까?
색상 변경을 확인하려면 회색조 이미지에서와 같이 스칼라 값이 아닌 점당 색상 값으로 구성된 벡터가 있습니다. 그러한 코드를 작성할 때 더주의를 기울여야합니다.
이미지에 뚜렷한 가장자리가 있습니까? 그들은 움직일 가능성이 있습니까?
그렇다면 가장자리 감지 알고리즘을 먼저 적용하고 (예 : Sobel 또는 Prewitt 변환으로 그라디언트 계산, 일부 임계 값 적용) 첫 번째 이미지의 가장자리와 두 번째 이미지의 가장자리를 비교할 수 있습니다.
이미지에 노이즈가 있습니까?
모든 센서는 약간의 노이즈로 이미지를 오염시킵니다. 저비용 센서는 더 많은 노이즈를 가지고 있습니다. 이미지를 비교하기 전에 노이즈 감소를 적용 할 수 있습니다. 흐림은 여기서 가장 단순하지만 최선의 방법은 아닙니다.
어떤 종류의 변화를 알고 싶습니까?
이는 이미지 간 차이에 사용할 표준 선택에 영향을 줄 수 있습니다.
이미지가 얼마나 많이 변경되었는지 측정하려면 Manhattan norm (절대 값의 합) 또는 zero norm (0이 아닌 요소 수)을 사용하십시오. 전자는 이미지가 얼마나 꺼져 있는지를 알려주고 후자는 얼마나 많은 픽셀이 다른지를 알려줍니다.
귀하의 이미지는 크기와 모양이 동일하고 노출이 다르면 잘 정렬되어 있다고 가정합니다. 간단하게하기 위해 컬러 (RGB) 이미지 인 경우에도 그레이 스케일로 변환합니다.
다음과 같은 수입품이 필요합니다.
import sys
from scipy.misc import imread
from scipy.linalg import norm
from scipy import sum, average
주요 기능, 두 개의 이미지 읽기, 그레이 스케일로 변환, 결과 비교 및 인쇄 :
def main():
file1, file2 = sys.argv[1:1+2]
# read images as 2D arrays (convert to grayscale for simplicity)
img1 = to_grayscale(imread(file1).astype(float))
img2 = to_grayscale(imread(file2).astype(float))
# compare
n_m, n_0 = compare_images(img1, img2)
print "Manhattan norm:", n_m, "/ per pixel:", n_m/img1.size
print "Zero norm:", n_0, "/ per pixel:", n_0*1.0/img1.size
비교하는 법. img1
및 img2
2D SciPy 배열은 여기에 있습니다 :
def compare_images(img1, img2):
# normalize to compensate for exposure difference, this may be unnecessary
# consider disabling it
img1 = normalize(img1)
img2 = normalize(img2)
# calculate the difference and its norms
diff = img1 - img2 # elementwise for scipy arrays
m_norm = sum(abs(diff)) # Manhattan norm
z_norm = norm(diff.ravel(), 0) # Zero norm
return (m_norm, z_norm)
파일이 컬러 이미지 인 경우 imread
강도를 얻기 위해 평균 RGB 채널 (마지막 배열 축) 인 3D 배열을 반환합니다. 회색조 이미지 (예 :)에는 필요하지 않습니다 .pgm
.
def to_grayscale(arr):
"If arr is a color image (3D array), convert it to grayscale (2D array)."
if len(arr.shape) == 3:
return average(arr, -1) # average over the last axis (color channels)
else:
return arr
정규화는 쉽지 않으므로 [0,255] 대신 [0,1]로 정규화하도록 선택할 수 있습니다. arr
여기 SciPy 배열이므로 모든 연산은 요소별로 수행됩니다.
def normalize(arr):
rng = arr.max()-arr.min()
amin = arr.min()
return (arr-amin)*255/rng
main
기능을 실행하십시오 .
if __name__ == "__main__":
main()
이제이 모든 것을 스크립트에 넣고 두 이미지에 대해 실행할 수 있습니다. 이미지를 자체와 비교하면 차이가 없습니다.
$ python compare.py one.jpg one.jpg
Manhattan norm: 0.0 / per pixel: 0.0
Zero norm: 0 / per pixel: 0.0
이미지를 흐리게 처리하고 원본과 비교하면 약간의 차이가 있습니다.
$ python compare.py one.jpg one-blurred.jpg
Manhattan norm: 92605183.67 / per pixel: 13.4210411116
Zero norm: 6900000 / per pixel: 1.0
PS 전체 compare.py 스크립트.
질문은 프레임이 거의 같은 비디오 시퀀스에 관한 것이며, 특이한 것을 찾고자 할 때, 관련이 될 수있는 몇 가지 대안을 언급하고자합니다.
“Learning OpenCV”책, 9 장 (이미지 부분 및 세그먼테이션) 및 10 (추적 및 모션)을 살펴 보는 것이 좋습니다. 전자는 백그라운드 빼기 방법을 사용하도록 가르치고, 후자는 광학 흐름 방법에 대한 정보를 제공합니다. 모든 메소드는 OpenCV 라이브러리에서 구현됩니다. 파이썬을 사용한다면 OpenCV ≥ 2.3을 사용하는 것이 좋습니다.cv2
파이썬 모듈 .
백그라운드 빼기의 가장 간단한 버전 :
보다 고급 버전은 모든 픽셀의 시계열을 고려하여 움직이지 않는 장면 (예 : 움직이는 나무 또는 잔디)을 처리합니다.
광학 흐름의 개념은 두 개 이상의 프레임을 가져 와서 모든 픽셀 (고밀도 광학 흐름) 또는 그 중 일부 (스파 스 광학 흐름)에 속도 벡터를 할당하는 것입니다. 희소 광학 흐름을 추정하기 위해 Lucas-Kanade 방법을 사용할 수 있습니다 (OpenCV에서도 구현 됨). 분명히 많은 흐름 (속도 필드의 최대 값에 대한 높은 평균)이 있으면 프레임에서 무언가가 움직이고 후속 이미지가 더 달라집니다.
히스토그램을 비교하면 연속 프레임 간의 갑작스러운 변화를 감지하는 데 도움이 될 수 있습니다. 이 접근법은 Courbon et al, 2010 에서 사용되었습니다 .
연속 프레임의 유사성. 두 개의 연속 프레임 사이의 거리가 측정됩니다. 너무 높으면 두 번째 프레임이 손상되어 이미지가 제거 된 것입니다. 쿨백 - 라이 블러 거리를 두 프레임에 대한 히스토그램, 또는 상호 엔트로피 :
여기서 p 와 q 는 프레임의 히스토그램입니다. 임계 값은 0.2로 고정됩니다.
RuntimeWarning: invalid value encountered in double_scalars
라인 (44) (에 return (arr-amin)*255/rng
)과를 ValueError: array must not contain infs or NaNs
라인 (30) (에 z_norm = norm(diff.ravel(), 0)
)
rng
0과 같습니다. 그냥 수표를 추가하고 설정rng = 1
간단한 해결책 :
이미지를 jpeg 로 인코딩하고 filesize 의 실질적인 변화를 찾으십시오 .
비디오 섬네일과 비슷한 것을 구현했으며 많은 성공과 확장 성을 가졌습니다.
PIL의 함수를 사용하여 두 이미지를 비교할 수 있습니다 .
import Image
import ImageChops
im1 = Image.open("splash.png")
im2 = Image.open("splash2.png")
diff = ImageChops.difference(im2, im1)
diff 객체는 모든 픽셀이 첫 번째 이미지에서 두 번째 이미지에서 해당 픽셀의 색상 값을 뺀 결과 인 이미지입니다. diff 이미지를 사용하면 몇 가지 작업을 수행 할 수 있습니다. 가장 간단한 것은 diff.getbbox()
함수입니다. 두 이미지 사이의 모든 변경 사항이 포함 된 최소 사각형을 알려줍니다.
PIL의 함수를 사용하여 여기에 언급 된 다른 것들의 근사치를 구현할 수 있습니다.
(a) 이미 제안 된 유클리드 거리 또는 (b) 표준화 된 상호 상관 법. 정규화 된 상호 상관은 단순한 상호 상관보다 조명 변화에 현저하게 더 강한 경향이 있습니다. Wikipedia는 정규화 된 상호 상관을 위한 공식을 제공합니다 . 더 정교한 방법도 있지만 훨씬 더 많은 작업이 필요합니다.
numpy와 같은 구문을 사용하여
dist_euclidean = sqrt (sum ((i1-i2) ^ 2)) / i1.size dist_manhattan = 합 (abs (i1-i2)) / i1.size dist_ncc = sum ((i1-평균 (i1)) * (i2-평균 (i2))) / ( (i1.size-1) * stdev (i1) * stdev (i2))
가정 i1
및 i2
2D 그레이 스케일 이미지의 배열입니다.
시도해 볼만한 사소한 일 :
두 이미지를 작은 썸네일 (예 : 64 x 64)로 리샘플링하고 썸네일을 픽셀 단위로 특정 임계 값과 비교합니다. 원본 이미지가 거의 같은 경우, 리샘플링 된 썸네일은 매우 유사하거나 정확히 동일합니다. 이 방법은 특히 저 조명 장면에서 발생할 수있는 노이즈를 처리합니다. 그레이 스케일을 사용하는 것이 더 나을 수도 있습니다.
나는 그들이 "충분히 다르다"면 어떻게 계산할 것인가에 대한 문제를 구체적으로 다루고 있습니다. 픽셀을 하나씩 빼는 방법을 알 수 있다고 가정합니다.
먼저, 아무 것도 변경 하지 않고 많은 이미지를 찍고 캡처, 이미지 시스템의 노이즈, JPEG 압축 아티팩트 및 조명의 순간 변화로 인해 픽셀이 변경되는 최대량을 찾습니다. . 아무것도 움직이지 않아도 1 또는 2 비트의 차이가 발생할 수 있습니다.
그런 다음 "실제"테스트의 경우 다음과 같은 기준을 원합니다.
따라서 E = 0.02, P = 1000 인 경우 단일 픽셀이 ~ 5 단위 이상 (8 비트 이미지로 가정)으로 변경되거나 1000보다 큰 경우 "차이"임을 의미합니다. 픽셀에 전혀 오류가 없었습니다.
이는 주로 추가 검사가 필요하지 않은 이미지를 신속하게 식별하기위한 우수한 "심사"기법으로 사용됩니다. "실패"한 이미지는 예를 들어 카메라가 비트를 흔들거나 조명 변경에 대해 더 강력한 경우 잘못된 긍정을 갖지 않는보다 정교하고 비싼 기술에 더 가깝습니다.
오픈 소스 프로젝트 인 OpenImageIO를 실행 하는데 , 여기에는 이와 같은 임계 값과 차이를 비교하는 "idiff"유틸리티가 포함되어 있습니다 (실제로는 더 정교합니다). 이 소프트웨어를 사용하지 않으려는 경우에도 소스를보고 어떻게 수행했는지 확인할 수 있습니다. 상업적으로 많이 사용되며이 임계 값 기술은 플랫폼과 플랫폼간에 약간의 차이가있을 수있는 "참조 이미지"와 함께 렌더링 및 이미지 처리 소프트웨어를위한 테스트 스위트를 가질 수 있도록 개발되었습니다. 그 결과 알고리즘이 "허용 오차 범위 내"작업을 원했습니다.
나는 직장에서 비슷한 문제가 있었고 이미지 변환 끝점을 다시 작성하고 있었고 새 버전이 이전 버전과 동일하거나 거의 동일한 출력을 생성하고 있는지 확인하고 싶었습니다. 그래서 나는 이것을 썼다 :
https://github.com/nicolashahn/diffimg
동일한 크기의 이미지와 픽셀 단위로 작동하는 각 채널의 값 차이를 측정합니다. R, G, B (, A), 해당 채널의 평균 차이를 취한 다음 그 차이를 평균화합니다. 모든 픽셀을 반환하고 비율을 반환합니다.
예를 들어, 10x10의 흰색 픽셀 이미지와 동일한 이미지이지만 하나의 픽셀이 빨간색으로 변경된 경우 해당 픽셀의 차이는 1/3 또는 0.33 ... (RGB 0,0,0 대 255,0,0) ) 및 다른 모든 픽셀은 0입니다. 총 100 픽셀 인 경우 0.33 ... / 100 = ~ 0.33 %의 이미지 차이입니다.
나는 이것이 OP 프로젝트에 완벽하게 작동 할 것이라고 생각합니다 (이것은 지금 매우 오래된 게시물이지만 파이썬에서 이미지를 비교하려는 미래의 StackOverflowers에 게시한다는 것을 알고 있습니다).
주어진 답변의 대부분은 조명 수준을 다루지 않습니다.
먼저 비교하기 전에 이미지를 표준 조명 수준으로 정규화합니다.
두 이미지 간의 유사성을 측정하는 또 다른 훌륭하고 간단한 방법입니다.
import sys
from skimage.measure import compare_ssim
from skimage.transform import resize
from scipy.ndimage import imread
# get two images - resize both to 1024 x 1024
img_a = resize(imread(sys.argv[1]), (2**10, 2**10))
img_b = resize(imread(sys.argv[2]), (2**10, 2**10))
# score: {-1:1} measure of the structural similarity between the images
score, diff = compare_ssim(img_a, img_b, full=True)
print(score)
다른 사람들이 이미지 유사성을 비교하는 더 강력한 방법에 관심이 있다면, Tensorflow를 사용하여 유사한 이미지를 측정하고 시각화하기위한 튜토리얼 과 웹 앱 을 만들었습니다 .
skimage
이 응용 프로그램에 사용하기 정말 좋습니다. from skimage.measure import compare_ssim, compare_mse
많이 사용 합니다. skimage.measure 문서 .
비슷한 이미지 질문 을 찾는 알고리즘을 보셨습니까 ? 제안을 확인하려면 확인하십시오.
프레임의 잔물결 변환을 제안합니다 (Haar 변환을 사용하여 C 확장을 작성했습니다). 그런 다음 두 그림 사이의 가장 큰 (비례 적으로) 웨이블릿 계수의 인덱스를 비교하면 수치 적 유사성 근사치를 얻을 수 있습니다.
답변이 너무 늦어 죄송합니다. 비슷한 작업을 수행 한 이후 어떻게 든 기여할 수 있다고 생각했습니다.
OpenCV를 사용하면 템플릿 일치를 사용할 수 있습니다. 당신이 말한대로 웹캠을 사용한다고 가정 :
팁 : max_val (또는 사용 된 방법에 따라 min_val)은 숫자와 숫자를 제공합니다. 백분율 차이를 얻으려면 동일한 이미지로 템플릿 일치를 사용하십시오. 결과는 100 %입니다.
예시하는 의사 코드 :
previous_screenshot = ...
current_screenshot = ...
# simplify both images somehow
# get the 100% corresponding value
res = matchTemplate(previous_screenshot, previous_screenshot, TM_CCOEFF)
_, hundred_p_val, _, _ = minMaxLoc(res)
# hundred_p_val is now the 100%
res = matchTemplate(previous_screenshot, current_screenshot, TM_CCOEFF)
_, max_val, _, _ = minMaxLoc(res)
difference_percentage = max_val / hundred_p_val
# the tolerance is now up to you
도움이 되길 바랍니다.
나는 삼각대에서 같은 카메라로 촬영 한 jpg 이미지로 많은 행운을 겪었습니다. 벡터 (3) 순차 이미지를 간단한 상관 알고리즘과 쌍으로 상관시켜 상관 계수를 얻습니다. r-square <0.9이면 두 이미지가 다르고 그 사이에 무언가가 발생했다고 말합니다.
이것은 내 구현에서 강력하고 빠릅니다 (Mathematica 7)
관심있는 이미지 부분을 가지고 놀아 볼 가치가 있습니다. 모든 이미지를 작은 영역으로 자르면 카메라에서 멀리 떨어져 있지만 중요한 변경 사항을 놓칠 수 있습니다.
파이썬 사용법을 모르겠지만 상관 관계도 확실하지 않습니까?
두 이미지의 히스토그램을 계산 한 다음 Bhattacharyya Coefficient 를 계산할 수 있습니다. 이 알고리즘은 매우 빠르며 크리켓 비디오의 샷 변화를 감지하는 데 사용했습니다 (C에서 openCV 사용)
하크 웨이블릿이 isk-daemon에 의해 어떻게 구현되는지 확인하십시오 . imgdb C ++ 코드를 사용하여 이미지 간 차이를 즉시 계산할 수 있습니다.
isk-daemon은 이미지 기반 웹 사이트 또는 소프트웨어에 컨텐츠 기반 (영상) 이미지 검색을 추가 할 수있는 오픈 소스 데이터베이스 서버입니다.
이 기술을 사용하면 모든 이미지 관련 웹 사이트 또는 소프트웨어 사용자가 위젯에서 원하는 이미지를 찾아 가장 유사한 이미지에 응답하거나 각 이미지 세부 사항 페이지에서 더 유사한 사진을 요청하도록 위젯에 스케치 할 수 있습니다.
나는 같은 문제가 있었고 베개의 ImageChops를 사용하여 동일한 크기의 두 이미지를 비교하여 흑백 diff 이미지를 만들고 히스토그램 값을 요약하는 간단한 파이썬 모듈을 작성했습니다.
이 점수를 직접 얻거나 전체 검정 대 흰색 차이에 비해 백분율 값을 얻을 수 있습니다.
또한 간단한 is_equal 함수가 포함되어 있으며 이미지 패스 아래 (및 포함)에 퍼지 임계 값을 제공 할 수 있습니다.
이 접근법은 매우 정교하지는 않지만 같은 문제로 어려움을 겪고있는 다른 사람들에게 유용 할 수 있습니다.
import os
from PIL import Image
from PIL import ImageFile
import imagehash
#just use to the size diferent picture
def compare_image(img_file1, img_file2):
if img_file1 == img_file2:
return True
fp1 = open(img_file1, 'rb')
fp2 = open(img_file2, 'rb')
img1 = Image.open(fp1)
img2 = Image.open(fp2)
ImageFile.LOAD_TRUNCATED_IMAGES = True
b = img1 == img2
fp1.close()
fp2.close()
return b
#through picturu hash to compare
def get_hash_dict(dir):
hash_dict = {}
image_quantity = 0
for _, _, files in os.walk(dir):
for i, fileName in enumerate(files):
with open(dir + fileName, 'rb') as fp:
hash_dict[dir + fileName] = imagehash.average_hash(Image.open(fp))
image_quantity += 1
return hash_dict, image_quantity
def compare_image_with_hash(image_file_name_1, image_file_name_2, max_dif=0):
"""
max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.
recommend to use
"""
ImageFile.LOAD_TRUNCATED_IMAGES = True
hash_1 = None
hash_2 = None
with open(image_file_name_1, 'rb') as fp:
hash_1 = imagehash.average_hash(Image.open(fp))
with open(image_file_name_2, 'rb') as fp:
hash_2 = imagehash.average_hash(Image.open(fp))
dif = hash_1 - hash_2
if dif < 0:
dif = -dif
if dif <= max_dif:
return True
else:
return False
def compare_image_dir_with_hash(dir_1, dir_2, max_dif=0):
"""
max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.
"""
ImageFile.LOAD_TRUNCATED_IMAGES = True
hash_dict_1, image_quantity_1 = get_hash_dict(dir_1)
hash_dict_2, image_quantity_2 = get_hash_dict(dir_2)
if image_quantity_1 > image_quantity_2:
tmp = image_quantity_1
image_quantity_1 = image_quantity_2
image_quantity_2 = tmp
tmp = hash_dict_1
hash_dict_1 = hash_dict_2
hash_dict_2 = tmp
result_dict = {}
for k in hash_dict_1.keys():
result_dict[k] = None
for dif_i in range(0, max_dif + 1):
have_none = False
for k_1 in result_dict.keys():
if result_dict.get(k_1) is None:
have_none = True
if not have_none:
return result_dict
for k_1, v_1 in hash_dict_1.items():
for k_2, v_2 in hash_dict_2.items():
sub = (v_1 - v_2)
if sub < 0:
sub = -sub
if sub == dif_i and result_dict.get(k_1) is None:
result_dict[k_1] = k_2
break
return result_dict
def main():
print(compare_image('image1\\815.jpg', 'image2\\5.jpg'))
print(compare_image_with_hash('image1\\815.jpg', 'image2\\5.jpg', 7))
r = compare_image_dir_with_hash('image1\\', 'image2\\', 10)
for k in r.keys():
print(k, r.get(k))
if __name__ == '__main__':
main()
두 이미지의 휘도 사이의 유클리드 거리 (예 : sqrt (차의 제곱의 합, 픽셀 단위))를 간단히 계산할 수 있으며 경험적 임계 값에 해당하면 동일하다고 생각합니다. 그리고 C 함수를 감싸는 것이 좋습니다.
두 개의 이미지가 어떻게 보이는지 / 얼마나 많이 보이는지를 평가하기위한 많은 메트릭이 있습니다.
기술적 인 문제가 아닌 과학적인 문제 여야한다고 생각하기 때문에 여기서는 코드를 작성하지 않을 것입니다.
일반적으로 질문은 이미지에 대한 인간의 인식과 관련이 있으므로 각 알고리즘은 인간의 시각 시스템 특성에 대한 지원을 갖습니다.
고전적인 접근 방식은 다음과 같습니다.
가시적 차이 예측기 : 이미지 충실도를 평가하기위한 알고리즘 ( https://www.spiedigitallibrary.org/conference-proceedings-of-spie/1666/0000/Visible-differences-predictor--an-algorithm-for-the-the- /10.1117/12.135952.short?SSO=1의 평가 )
이미지 품질 평가 : 오류 가시성에서 구조적 유사성까지 ( http://www.cns.nyu.edu/pub/lcv/wang03-reprint.pdf )
FSIM : 이미지 품질 평가를위한 기능 유사성 지수 ( https://www4.comp.polyu.edu.hk/~cslzhang/IQA/TIP_IQA_FSIM.pdf )
그중에서도 SSIM (Image Quality Assessment : Error Visibility에서 Structural Similarity)은 계산하기가 가장 쉽고 "그라디언트 유사성에 기반한 이미지 품질 평가"( https : //www.semanticscholar .org / paper / Image-Quality-Assessment-Based-on-Gradient-Liu-Lin / 2b819bef80c02d5d4cb56f27b202535e119df988 ).
더 많은 다른 접근법이 있습니다. 예술에 관심이 있거나 관심이 있다면 Google Scholar를보고 '시각적 차이', '이미지 품질 평가'등을 검색하십시오.