Python 은 Opencv 기반 으로 비슷 한 그림 두 장 을 식별 합 니 다.

8201 단어 PythonOpencv그림.
인터넷 에서 python 이 이미지 인식 에 관 한 글 을 본 후에 python 의 기능 이 너무 강하 다 는 것 을 진심으로 느 꼈 기 때문에 이 글 들 을 정리 하고 자신의 지식 체 계 를 구축 합 니 다.물론 이미지 인식 이라는 화 제 는 컴퓨터 과학 의 한 가지 로 서 본 고 에서 몇 마디 만 간단하게 말 할 수 없 기 때문에 본 고 는 기본 산법 의 과학 보급 방향 만 만 만 한다.이 를 소개 하 는 블 로 그 를 보 았 지만 PIL 의 Image 로 이 루어 져 귀 찮 았 기 때문에 Opencv 라 이브 러 리 를 이용 하여 더욱 간결 하 게 이 루어 졌 다.
관련 배경
비슷 한 이미지 두 장 을 식별 하려 면 우 리 는 감성 적 으로 어떤 과정 인지 이야기 해 야 한다.우선 우 리 는 이 두 장의 사진 의 유형,예 를 들 어 풍경 사진 인지 인물 사진 인지 구분 할 것 이다.풍경 사진 에서 사막 인지 바다 인지 인물 사진 에서 두 사람 은 모두 국자 얼굴 인지,아니면 해바라기씨 얼굴 인지...하하...........................................................
그러면 기계 의 측면 에서 도 마찬가지다.먼저 이미지 의 특징 을 식별 한 다음 에 비교한다.
훈련 을 거치 지 않 은 컴퓨터(즉 모델 구축)에 서 는 컴퓨터 가 바다 가 무엇 인지,사막 이 무엇 인지 구분 하기 어 려 운 것 이 분명 하 다.그러나 컴퓨터 는 이미지 의 픽 셀 값 을 쉽게 식별 할 수 있다.
따라서 이미지 인식 에서 색채 특징 이 가장 많이 사용 된다.나머지 자주 사용 하 는 특징 은 무늬 특징,모양 특징 과 공간 관계 특징 등 이 있다)

직사각형 색상 집합 색상 매트릭스 벡터 관련 그림
직사 도 계산법
여기 서 먼저 직사 도 로 간단하게 이야기 합 니 다.
먼저 꽃 나 비 를 사랑 하 는 그림 을 빌려 쓰 고,
[사진 업로드 실패...(image-6ca66e-1617780875489)]
육안 으로 볼 때 이 두 장의 그림 도 대략 80%가 비슷 하 다.Python 에서 opencv 의 calcHist()방법 으로 직사 도 데 이 터 를 얻 었 습 니 다.돌아 온 결 과 는 목록 입 니 다.matplotlib 를 사용 하여 이 두 그림 의 직사 도 데이터 그림 을 그 렸 습 니 다.

예,우 리 는 두 장의 그림 의 직사 도 가 비교적 겹 치 는 것 을 뚜렷하게 발견 할 수 있 습 니 다.따라서 직사 도 를 이용 하여 두 장의 그림 이 비슷 한 지 아 닌 지 를 판단 하 는 방법 은 직사 도 의 중합 정 도 를 계산 하면 된다 는 것 이다.계산 방법 은 다음 과 같다.

그 중에서 gi 와 si 는 각각 두 곡선의 i 번 째 점 을 가리킨다.
마지막 으로 계 산 된 결 과 는 그 유사 성 이다.
그러나 이런 방법 은 뚜렷 한 약점 이 있다.바로 그 가 색채 의 전체적인 분포 에 따라 볼 때 색채 의 국부 분포 와 색채 가 처 한 위 치 를 묘사 할 수 없다 는 것 이다.
즉,한 장의 그림 이 파란색 을 위주 로 하고 내용 이 푸 른 하늘 이 며 다른 한 장의 그림 도 파란색 을 위주 로 하지만 내용 은 여동생 이 파란색 치 마 를 입 었 다 면 이 알고리즘 은 이 두 장의 그림 이 비슷 하 다 고 생각 할 수 있다.
이 약점 을 완화 시 키 는 방법 중 하 나 는 Image 의 crop 방법 을 이용 하여 그림 을 등분 한 다음 에 그 싱크로 율 을 각각 계산 하고 마지막 으로 종합 적 으로 고려 하 는 것 이다.
이미지 지문 과 한 명 거리
아래 의 다른 유사 도 를 판별 하 는 방법 을 소개 하기 전에 먼저 개념 을 보충 하 자.첫 번 째 는 이미지 지문.
이미지 지문 은 사람의 지문 과 마찬가지 로 신분 의 상징 이 고 이미지 지문 은 간단하게 말 하면 이미 지 를 일정한 해시 알고리즘 에 따라 연산 을 거 쳐 나 온 바 이 너 리 숫자 이다.
여기까지 말 하면 한 명 거리의 개념 을 이 끌 어 낼 수 있다.
만약 에 한 조 의 바 이 너 리 데이터 가 101 이 고 다른 한 조 가 111 이 라면 첫 번 째 조 의 두 번 째 데이터 0 을 1 로 바 꾸 면 두 번 째 조 의 데이터 111 이 될 수 있 기 때문에 두 조 의 데이터 한 명 거 리 는 1 이다.
쉽게 말 하면 한 밍 거 리 는 한 조 의 이 진 데이터 가 다른 데이터 로 바 뀌 는 데 필요 한 절차 이다.분명히 이 수 치 는 두 장의 그림 의 차 이 를 평가 할 수 있 고 한 밍 거리 가 작 을 수록 싱크로 율 이 높다 는 것 을 의미한다.한 명 거 리 는 0,즉 두 장의 그림 이 완전히 같다 는 것 을 의미한다.
어떻게 한 명 거 리 를 계산 할 수 있 는 지 아래 세 가지 해시 알고리즘 을 보 세 요.
평균 해시 법(aHash)
이 알고리즘 은 그 레이스 케 일 맵 의 픽 셀 과 평균 값 을 비교 하여 이 루어 집 니 다.
일반 단계:
1.그림 크기 조정,일반 크기 는 8*8,64 픽 셀 입 니 다.
2.그 레이스 케 일 로 전환
3.평균 값 계산:그 레이스 케 일 처리 후 그림 의 모든 픽 셀 점 의 평균 값 을 계산 하고 numpy 의 mean()으로 직접 계산 하면 됩 니 다.
4.픽 셀 그 레이스 케 일 비교:그 레이스 케 일 그림 의 모든 픽 셀 을 옮 겨 다 니 며 평균 값 보다 크 면 1 로 기록 합 니 다.그렇지 않 으 면 0 입 니 다.
5.정보 지문 획득:비트 64 개 를 조합 하여 순 서 를 임의로 일치 시 킵 니 다.
마지막 으로 두 장의 그림 의 지문 을 비교 해 한 명 거 리 를 얻 으 면 된다.
감지 해시 알고리즘(pHash)
평균 해시 알고리즘 은 너무 엄격 하고 정확 하지 않 으 며 미리 보기 그림 을 검색 하기에 더욱 적합 합 니 다.더 정확 한 결 과 를 얻 기 위해 감지 해시 알고리즘 을 선택 할 수 있 습 니 다.DCT(이산 코사인 변환)를 사용 하여 빈 도 를 낮 추 는 방법 을 사용 합 니 다.
일반 단계:
  • 축소 사진:32*32 는 비교적 좋 은 크기 로 DCT 계산
  • 에 편리 하 다.
  • 그 레이스 케 일 로 전환
  • DCT 계산:Opencv 에서 제공 하 는 dct()방법 을 이용 하여 입력 한 이미지 가 32 비트 부동 소수점 형 이 어야 하 므 로 numpy 의 float 32 를 이용 하여 변환
  • 축소 DCT:DCT 계산 후의 행렬 은 32*32 이 고 왼쪽 상단 의 8*8 을 유지 하 며 이 대표 적 인 그림 들 의 최저 주파수
  • 평균 값 계산:DCT 축소 후의 모든 픽 셀 점 의 평균 값 을 계산 합 니 다.
  • DCT 를 더욱 줄인다.평균치 보다 큰 기록 은 1 이 고,반대로 0 이다.
  • 정보 지문:64 개의 정보 위 치 를 조합 하여 순서 가 임의로 일치 성 을 유지한다.
  • 마지막 으로 두 장의 그림 의 지문 을 비교 해 한 명 거 리 를 얻 으 면 된다.
    dHash 알고리즘
    pHash 에 비해 dHash 의 속도 가 훨씬 빠 릅 니 다.aHash 에 비해 dHash 는 효율 이 거의 같은 상황 에서 효과 가 더 좋 고 그 라 데 이 션 을 바탕 으로 이 루어 집 니 다.
    단계:
  • 그림 축소:9*8 크기 로 축소 하여 72 픽 셀
  • 그 레이스 케 일 로 전환
  • 계산 차이 값:dHash 알고리즘 은 인접 픽 셀 사이 에서 작 동 합 니 다.그러면 줄 당 9 개의 픽 셀 사이 에 8 개의 차이 가 생 겼 고 모두 8 줄 이면 64 개의 차이 값
  • 이 생 겼 습 니 다.
  • 지문 획득:왼쪽 픽 셀 이 오른쪽 보다 밝 으 면 1 로 기록 하고 그렇지 않 으 면 0 으로 기록 합 니 다.
  • 마지막 으로 두 장의 그림 의 지문 을 비교 하여 한 명 거 리 를 얻 으 면 된다
  • 전체 코드 는 다음 과 같 습 니 다.
    
    # -*- coding: utf-8 -*- 
    #   python              
     
    import cv2 
    import numpy as np 
    from matplotlib import pyplot as plt 
     
    #                     
    def classify_gray_hist(image1,image2,size = (256,256)): 
     #        
     #               
     #              ,          , 
     #           ,           
     # bins   16 
     image1 = cv2.resize(image1,size) 
     image2 = cv2.resize(image2,size) 
     hist1 = cv2.calcHist([image1],[0],None,[256],[0.0,255.0]) 
     hist2 = cv2.calcHist([image2],[0],None,[256],[0.0,255.0]) 
     #          
     plt.plot(range(256),hist1,'r') 
     plt.plot(range(256),hist2,'b') 
     plt.show() 
     #           
     degree = 0 
     for i in range(len(hist1)): 
     if hist1[i] != hist2[i]: 
     degree = degree + (1 - abs(hist1[i]-hist2[i])/max(hist1[i],hist2[i])) 
     else: 
     degree = degree + 1 
     degree = degree/len(hist1) 
     return degree 
     
    #               
    def calculate(image1,image2): 
     hist1 = cv2.calcHist([image1],[0],None,[256],[0.0,255.0]) 
     hist2 = cv2.calcHist([image2],[0],None,[256],[0.0,255.0]) 
     #           
     degree = 0 
     for i in range(len(hist1)): 
     if hist1[i] != hist2[i]: 
     degree = degree + (1 - abs(hist1[i]-hist2[i])/max(hist1[i],hist2[i])) 
     else: 
     degree = degree + 1 
     degree = degree/len(hist1) 
     return degree 
     
    #                    
    def classify_hist_with_split(image1,image2,size = (256,256)): 
     #    resize ,       ,            
     image1 = cv2.resize(image1,size) 
     image2 = cv2.resize(image2,size) 
     sub_image1 = cv2.split(image1) 
     sub_image2 = cv2.split(image2) 
     sub_data = 0 
     for im1,im2 in zip(sub_image1,sub_image2): 
     sub_data += calculate(im1,im2) 
     sub_data = sub_data/3 
     return sub_data 
     
    #          
    def classify_aHash(image1,image2): 
     image1 = cv2.resize(image1,(8,8)) 
     image2 = cv2.resize(image2,(8,8)) 
     gray1 = cv2.cvtColor(image1,cv2.COLOR_BGR2GRAY) 
     gray2 = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY) 
     hash1 = getHash(gray1) 
     hash2 = getHash(gray2) 
     return Hamming_distance(hash1,hash2) 
     
    def classify_pHash(image1,image2): 
     image1 = cv2.resize(image1,(32,32)) 
     image2 = cv2.resize(image2,(32,32)) 
     gray1 = cv2.cvtColor(image1,cv2.COLOR_BGR2GRAY) 
     gray2 = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY) 
     #          ,   dct   
     dct1 = cv2.dct(np.float32(gray1)) 
     dct2 = cv2.dct(np.float32(gray2)) 
     #      8*8,            
     #        c++   opencv        
     #  python       ,                  
     dct1_roi = dct1[0:8,0:8] 
     dct2_roi = dct2[0:8,0:8] 
     hash1 = getHash(dct1_roi) 
     hash2 = getHash(dct2_roi) 
     return Hamming_distance(hash1,hash2) 
     
    #      ,  hash 
    def getHash(image): 
     avreage = np.mean(image) 
     hash = [] 
     for i in range(image.shape[0]): 
     for j in range(image.shape[1]): 
     if image[i,j] > avreage: 
     hash.append(1) 
     else: 
     hash.append(0) 
     return hash 
     
     
    #        
    def Hamming_distance(hash1,hash2): 
     num = 0 
     for index in range(len(hash1)): 
     if hash1[index] != hash2[index]: 
     num += 1 
     return num 
     
     
    if __name__ == '__main__': 
     img1 = cv2.imread('10.jpg') 
     cv2.imshow('img1',img1) 
     img2 = cv2.imread('11.jpg') 
     cv2.imshow('img2',img2) 
     degree = classify_gray_hist(img1,img2) 
     #degree = classify_hist_with_split(img1,img2) 
     #degree = classify_aHash(img1,img2) 
     #degree = classify_pHash(img1,img2) 
     print degree 
     cv2.waitKey(0) 
    
    이상 은 Python 이 Opencv 를 바탕 으로 비슷 한 그림 두 장 을 식별 하 는 상세 한 내용 입 니 다.python 이 비슷 한 그림 을 식별 하 는 데 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

    좋은 웹페이지 즐겨찾기