이미지 처리 : 'Coca-Cola Can'인식을위한 알고리즘 개선


1658

지난 몇 년 동안 내가 작업 한 가장 흥미로운 프로젝트 중 하나는 이미지 처리 에 관한 프로젝트였습니다 . 목표는 코카콜라 '캔' 을 인식 할 수있는 시스템을 개발하는 것이 었습니다 ( '캔'이라는 단어를 강조하고 있습니다. 아래의 샘플을 볼 수 있으며, 스케일과 회전이 있는 녹색 사각형 으로 캔을 인식 할 수 있습니다 .

템플릿 매칭

프로젝트에 대한 몇 가지 제약 :

  • 배경이 시끄러울 수 있습니다.
  • 캔은 어떤 가질 수 규모 또는 회전 (합리적인 범위 내) 또는 방향을.
  • 이미지에 약간의 퍼지 현상이있을 수 있습니다 (컨투어가 완전히 직선이 아닐 수 있음).
  • 이미지에 코카콜라 병이있을 수 있으며 알고리즘은 만 감지해야합니다 !
  • 이미지의 밝기는 많이 다를 수 있습니다 (따라서 컬러 감지에 "너무 많이"의존 할 수 없습니다).
  • 캔은 부분적으로 양쪽 또는 중간에 숨겨진 가능성이 일부 병 뒤에 숨겨 질 수 있습니다.
  • 이미지 에는 이 전혀 없을 수 있습니다 .이 경우 아무것도 찾지 않고 그렇게 말하는 메시지를 작성해야했습니다.

따라서 다음과 같은 까다로운 것들로 끝날 수 있습니다 (이 경우 내 알고리즘이 완전히 실패했습니다).

총 실패

나는이 프로젝트를 얼마 전에 해왔고, 그것을하는 데 많은 재미가 있었고, 적절한 구현을했다. 내 구현에 대한 세부 정보는 다음과 같습니다.

언어 : OpenCV 라이브러리를 사용하여 C ++로 작성했습니다 .

전처리 : 이미지 전처리, 즉 알고리즘에 제공하기 위해 이미지를 원시 형식으로 변환하기 위해 두 가지 방법을 사용했습니다.

  1. RGB에서 HSV로 색상 도메인을 변경 하고 "적색"색조를 기준으로 필터링, 주황색과 같은 색상을 피하기 위해 특정 임계 값을 초과하는 채도 및 어두운 톤을 피하기 위해 낮은 값을 필터링합니다. 최종 결과는 이진 흑백 이미지로 모든 흰색 픽셀이이 임계 값과 일치하는 픽셀을 나타냅니다. 분명히 이미지에는 여전히 많은 문제가 있지만, 이렇게하면 작업해야하는 크기가 줄어 듭니다. 이진화 된 이미지
  2. 잡음을 줄이기 위해 중간 필터링 (모든 이웃의 중간 픽셀 값을 취하고 픽셀을이 값으로 대체)을 사용하는 잡음 필터링.
  3. Canny Edge Detection Filter 를 사용하여 2 가지 선행 단계 후 모든 항목의 윤곽을 얻습니다. 윤곽 감지

알고리즘 :이 작업을 위해 선택한 알고리즘 자체는 기능 추출에 대한 훌륭한 책에서 발췌 한 Generalized Hough Transform ( 일반 Hough Transform 과는 매우 다른)이라고합니다. 기본적으로 몇 가지 사항이 있습니다.

  • 분석 방정식 (여기서는 경우)을 몰라도 우주에서 물체를 묘사 할 수 있습니다.
  • 기본적으로 스케일링 계수와 회전 계수의 모든 조합에 대해 이미지를 테스트하므로 스케일링 및 회전과 같은 이미지 변형에 강합니다.
  • 알고리즘이 "학습"할 기본 모델 (템플릿)을 사용합니다.
  • 등고선 이미지에 남아있는 각 픽셀은 모델에서 배운 내용에 따라 물체의 중심 (중력)으로 간주되는 다른 픽셀에 투표합니다.

결국, 당신은 투표의 열지 도로 끝납니다. 예를 들어, 여기에서 캔의 윤곽의 모든 픽셀은 중력 중심에 투표 할 것입니다. 따라서 당신은 같은 픽셀에 많은 투표를 할 것입니다. 다음과 같이 히트 맵에서 피크를 볼 수 있습니다.

GHT

일단 그것을 가져 오면 간단한 임계 값 기반 휴리스틱은 중심 픽셀의 위치를 ​​제공하여 스케일과 회전을 유도 한 다음 그 주위에 작은 사각형을 그릴 수 있습니다 (최종 스케일과 회전 계수는 분명히 원본 템플릿). 이론 상으로는 ...

결과 : 이제이 방법이 기본적인 경우에는 효과가 있었지만 일부 영역에서는 심각하게 부족했습니다.

  • 그것은되어 매우 느리게 ! 나는 이것을 충분히 강조하고 있지 않다. 30 개의 테스트 이미지를 처리하는 데 거의 하루 종일이 필요했습니다. 분명히 일부 캔이 매우 작기 때문에 회전 및 평행 이동에 대한 배율이 매우 높았 기 때문입니다.
  • 병이 이미지에있을 때 완전히 잃어 버렸고 어떤 이유로 든 캔 대신 병을 거의 항상 발견했습니다 (병이 더 커서 픽셀이 많기 때문에 더 많은 표를 얻었을 것입니다)
  • 퍼지 이미지는 투표가 중앙의 임의의 위치에서 픽셀로 끝나서 매우 시끄러운 히트 맵으로 끝나기 때문에 좋지 않았습니다.
  • 평행 이동과 회전의 불균형은 달성되었지만 방향이 아닙니다. 즉, 카메라 대물 렌즈를 직접 향하지 않은 캔은 인식되지 않았습니다.

언급 된 네 가지 특정 문제 를 해결하기 위해 독점적으로 OpenCV 기능을 사용하여 특정 알고리즘을 개선 할 수 있습니까 ?

질문을하는 사람 만이 배워야 할 것이 아니라고 생각하는 사람들도 있습니다. :)


45
이 질문은 dsp.stackexchange.com 또는 stats.stackexchange.com에서 더 적합하다고 말할 수 있으며 해당 사이트에서도 다시 질문하는 것이 좋습니다.
ely

49
여기서 가장 먼저해야 할 일은 다른 실패 사례가 발생 하는 이유 를 분석 하는 것입니다. 예를 들어, 병이이기는 곳, 이미지가 희미한 곳 등의 예를 분리하고 통계 분석을 수행하여 허프 표현과 감지하고자하는 표현의 차이를 알아냅니다. 다른 접근 방법에 대해 배울 수있는 훌륭한 장소는 여기여기에
엘리

7
@stacker가 좋은 지적입니다. 속도를 위해 히스토그램 방향 그라디언트와 같은 저렴한 컴퓨팅 기능을 원합니다. 정말 순진한 첫 번째 접근 방식은 일부 교육 이미지에서 여러 캔 사각형에 수동으로 레이블을 지정하고 이러한 플러스 임의의 음수 예제를 사용하여 SVM 또는 의사 결정 트리 분류기를 학습하는 것입니다. 교육 시간이 오래 걸리지 만 새로운 이미지의 실행 속도는 훨씬 빨라집니다. 올바른 참조를 포함시킬 자유 시간이 더 많아지면이 방법을 작성할 계획입니다.
ely April

9
reCAPTCHA 와 비슷한 접근법은 어떻습니까? ;)
George Duckett

39
왜 이것이 dsp.stackexchange.com 에서 이동 되었습니까 ? 그것은 사이트가 stackoverflow o_O보다 더 적합한 것 같습니다
BlueRaja-Danny Pflughoeft

답변:


672

다른 방법은 SIFT ( scale-invariant feature transform ) 또는 SURF ( Speeded Up Robust Features )를 사용하여 피처 (키포인트)를 추출하는 것 입니다.

OpenCV 2.3.1 에서 구현됩니다 .

Features2D + Homography의 기능을 사용하여 알려진 객체를 찾기위한 멋진 코드 예제를 찾을 수 있습니다.

두 알고리즘 모두 스케일링과 회전에 변하지 않습니다. 기능과 함께 작동 하므로 충분한 키포인트가 보이는 한 폐색 도 처리 할 수 ​​있습니다 .

여기에 이미지 설명을 입력하십시오

이미지 소스 : 튜토리얼 예

SIFT는 수백 ms가 걸리지 만 SURF는 조금 빠르지 만 실시간 애플리케이션에는 적합하지 않습니다. ORB는 회전 불변성과 관련하여 약한 FAST를 사용합니다.

원본 논문


6
@stacker에 동의합니다. SIFT는 탁월한 선택입니다. 스케일 및 회전 작업에 매우 견고합니다. 원근 변형에 대해 다소 견고합니다 (스태커에서 제안한대로 원하는 객체의 원근 뷰가 다른 템플릿 데이터베이스로 개선 할 수 있음). 내 경험에서 Achilles의 발 뒤꿈치는 강력한 조명 변형과 매우 비싼 계산입니다. Java 구현을 모른다. OpenCV 구현을 알고 있으며 실시간 성능에 적합한 GPU c ++ / Windows ( SiftGPU ) 구현을 사용했습니다.

31
경고 참고 사항 : SIFT / SURF를 좋아하고 그들이 한 일에 대해 특허권이 부족합니다. 이것은 수있는 지리적 위치 AFAIK 등 조건의 수에 따라 문제.
Agos

12
따라서 특허 문제가없는 OpenCV의 ORB 또는 FREAK를 사용해보십시오. ORB는 SIFT보다 훨씬 빠릅니다. ORB 내 경험의 규모와 가벼운 변화로 조금 나쁘지만 직접 테스트하십시오.
Rui Marques

66
이것을 어떻게 대답으로 받아 들일 수 있습니까? 어떤 기능 설명 자도 병과 캔을 구별 할 수 없습니다. 모두 변하지 않는 로컬 패턴 설명자를 봅니다. SIFT, SURF, ORB, FREAK 등이 기능 일치에 도움이 될 수 있지만 동의, 병 대 캔 등과 같은 질문의 다른 부분은 어떻습니까? 아마도 첫 번째 결과는이 답변 일 것입니다.
G453

11
@ G453 당신은 절대적으로 맞습니다! 아마도 그는 SHIFT의 성능에 매료되어 피처 추출과 매칭이 문제가 아니라는 것을 잊었습니다 ...
sepdek

383

작업 속도를 높이기 위해 임의의 이미지 / 객체를 찾지 말고 특히 Coca-Cola 로고가있는 것을 찾으라는 사실을 이용합니다. 이 로고는 매우 독특하며, 주파수 영역, 특히 RGB의 빨간색 채널에서 특징적인 비 변형 서명이 있어야하기 때문에 중요합니다. 즉, 가로 스캔 라인 (가로로 정렬 된 로고에서 훈련 됨)이 만나는 빨간색에서 흰색에서 빨간색으로 번갈아 나타나는 패턴은 로고의 중심 축을 통과 할 때 독특한 "리듬"을 갖게됩니다. 이 리듬은 다른 스케일과 방향으로 "속도를 높이거나" "느리게"하지만 비례 적으로 동일하게 유지됩니다. 로고를 통해 수평 및 수직으로 수십 개의 스캔 라인을 식별 / 정의 할 수 있습니다. 항성 패턴으로. 이것을 "서명 스캔 라인"이라고 부릅니다.

서명 스캔 라인

대상 이미지에서이 서명을 검색하는 것은 이미지를 가로로 스캔하는 간단한 문제입니다. 빨간색 채널에서 고주파수 (빨간색 영역에서 흰색 영역으로의 이동을 나타냄)를 찾은 후 발견되면 훈련 세션에서 식별 된 주파수 리듬 중 하나가 따르는 지 확인하십시오. 일치하는 것이 발견되면 로고에서 스캔 라인의 방향과 위치를 즉시 알 수 있으므로 (훈련 중에 해당 항목을 추적하는 경우) 로고의 경계를 식별하는 것이 쉽지 않습니다.

이것이 선형 효율적인 알고리즘이 아니거나 거의 그렇지 않은 경우 놀랍습니다. 그것은 당신의 병-병 차별을 다루지는 않지만, 적어도 당신은 로고를 가질 것입니다.

(업데이트 : 병 인식을 위해 로고 옆에있는 콜라 (갈색 액체), 즉 병 내부를 찾거나 빈 병의 경우 항상 뚜껑 이 있는 뚜껑 을 찾습니다 로고와 동일한 기본 모양, 크기 및 거리이며 일반적으로 모두 흰색 또는 빨간색입니다 로고와 관련하여 캡이 있어야 하는 단색 타원형 모양을 검색 하십시오. 물론 완벽한 목표는 아닙니다. 쉬운 것을 빨리 찾으십시오 .)

(이미지 처리 날짜 이후 몇 년이 지났으므로이 제안을 높은 수준으로 개념적으로 유지했습니다. 사람의 눈이 어떻게 작동하는지 또는 적어도 뇌가 어떻게 작동하는지 대략적으로 생각할 수 있습니다.)


24
그것은 큰 제안입니다. 특히이 알고리즘은 많은 잘못된 부정이있을지라도 매우 빠르다는 사실을 특히 좋아합니다. 나의 숨겨진 목표 중 하나는 로봇 공학에이 탐지 기능을 실시간으로 사용하는 것입니다.
Charles Menguy

42
그렇습니다. 근사 알고리즘이 대부분의 실시간 실제 모델링 작업에 필수적 이라는 것은 종종 (정밀도로 특징 지어지는 분야에서) 잊혀 집니다. ( 이 개념을 바탕으로 논문작성 했습니다.) 제한된 지역에 대해 시간 요구 알고리즘을 저장하여 오 탐지를 제거합니다. 그리고 로봇 공학에서는 일반적으로 단일 이미지에만 국한되지 않는다는 것을 기억하십시오. 빠른 로봇은 모바일 로봇을 가정 할 때 정교한 알고리즘이 하나보다 많은 시간을 들여 다른 각도에서 수십 개의 이미지를 검색하여 허위 부정을 크게 줄일 수 있습니다.
kmote

29
Coca-Cola 로고 를 매우 빠르게 감지 하기 위해 바코드 스캐너에 얼마의 양을 사용하는 아이디어가 좋습니다 . +1!
Li-aung Yip

8
이 경우 서명을 찾는 문제는 캔을 반대편으로 돌리면 (즉, 서명을 숨기면) 알고리즘이 캔을 감지하지 못한다는 것입니다.
karlphillip

34
@karlphillip : 당신이 서명을 숨길 경우, 즉, 로고, 다음 어떤 로고를 찾고에 따라 방법은 실패 할 것입니다.
Li-aung Yip

162

재미있는 문제 : 병 이미지를 보았을 때 캔 이미지라고 생각했습니다. 그러나 인간으로서 내가 차이점을 말한 것은 그것이 병이기도하다는 것을 알았습니다 ...

캔과 병을 구별하기 위해 먼저 병을 스캔하는 것은 어떻습니까? 하나를 찾으면 캔을 찾기 전에 라벨을 가리십시오.

이미 캔을하고 있다면 구현하기가 어렵지 않습니다. 실제 단점은 처리 시간이 두 배가된다는 것입니다. (그러나 실제 응용 프로그램을 미리 생각하면 결국 병을 만들고 싶을 것입니다. ;-)


5
그러나 나는 그것에 대해서도 생각했지만 그것을 할 시간이별로 없었습니다. 병은 주로 스케일 캔처럼 보이기 때문에 어떻게 인식합니까? 나는 빨간 마개도 찾고 생각하고 병에 걸린 센터와 정렬되어 있는지 확인했지만 그다지 강력하지는 않습니다.
Charles Menguy

42
"코카콜라"와 평행 한 빨간색 캡 (또는 링)이 있으면 병일 가능성이 높습니다.
Lukasz Madon

@linker 캔에 대한 알고리즘을 어떻게 훈련 시켰습니까? 캔의 예가 있습니까? 병의 예에 대한 훈련은 어떻습니까?
siamii

1
이 알고리즘의 장점은 훈련 할 템플릿 이 하나만 필요하다는 것입니다. 그런 다음 다른 변형 캔과 일치하도록 모든 변형을 적용합니다. 이 템플릿의 이진화 및 등고선 기반 버전을 사용하여 훈련 했으므로 캔과 병의 유일한 차이점은 플러그 뿐이지 만 중력 중심이 가장자리에 있기 때문에 잘못된 긍정을 가져올 수 있습니다. 또는 병 외부. 시도해 볼만한 가치가 있습니다. 그러나 그것은 나의 처리 시간을 두 배로 할 것이고 나는 울 것이다;)
Charles Menguy

7
본질적으로 이것은 합리적인 방향입니다. 나는 약간 다른 말로 표현했다. 먼저 모든 후보자를 찾은 다음 각 후보에 대해 병인지, 캔인지, 아니면 다른 것인지 결정한다.
MSalters

131

두 번째 이미지에서 병과 캔을 구분하는 것이 어렵지 않습니까 (병의 투명 영역이 숨겨져있는 경우)?

그들은 매우 작은 영역을 제외하고는 거의 동일합니다 (즉, 캔 상단의 너비는 약간 작지만 병의 포장지는 전체 너비가 동일하지만 약간의 변경이 있습니까?)

내 마음에 온 첫 번째 일은 병의 빨간색 상단을 확인하는 것이 었습니다. 그러나 병의 상단이 없거나 부분적으로 숨겨진 경우 (위에서 언급 한 것처럼) 여전히 문제입니다.

두 번째로 생각한 것은 병의 투명성입니다. OpenCV에는 이미지에서 투명한 객체를 찾는 작업이 있습니다. 아래 링크를 확인하십시오.

특히 유리를 얼마나 정확하게 감지하는지 확인하려면 다음을 살펴보십시오.

그들의 구현 결과를보십시오 :

여기에 이미지 설명을 입력하십시오

그들은이 논문 이 K. McHenry와 J. Ponce (CVPR 2006) 의 논문 “유리를 찾기위한 측지 학적 능동 윤곽 프레임 워크” 의 구현이라고 말한다 .

귀하의 경우에는 약간 도움이 될 수 있지만 병이 채워지면 문제가 다시 발생합니다.

그래서 여기서는 병의 투명한 몸체를 먼저 검색하거나 두 개의 투명한 물체에 측면으로 연결된 빨간색 영역을 찾을 수 있습니다. (이상적으로 작업 할 때 이미지는 다음과 같습니다.)

여기에 이미지 설명을 입력하십시오

이제 노란색 영역, 즉 병의 레이블을 제거하고 알고리즘을 실행하여 캔을 찾을 수 있습니다.

어쨌든이 솔루션은 다른 솔루션과는 다른 문제가 있습니다.

  1. 병이 비어있는 경우에만 작동합니다. 이 경우 두 검은 색 사이의 빨간색 영역을 검색해야합니다 (Coca Cola 액체가 검은 색인 경우).
  2. 투명한 부분을 덮으면 또 다른 문제가 발생합니다.

그러나 어쨌든 그림에 위의 문제가 없으면 더 나은 방법으로 보입니다.


+1 나는 이것에 대해 생각했고이 방법을 구현하려고했다. 그러나 @linker는 자신의 이미지 세트를 공유하여 더 많은 추측을 할 수 있도록해야합니다.
karlphillip

그래 .. 더 많은 이미지가 있으면 좋겠다고 생각합니다.
Abid Rahman K

병 / 캔 레이블 만 있고 병 뚜껑 또는 투명도의 다른 구별 요소가 없거나 상단 / 하단이 없는지 고려합니다.-병의 너비는 캔의 너비와 다릅니다.
Ken

병의 로고 앞에 캔을 놓으면 어떻게됩니까?
AlgoRythm

51

이 문제에 대한 대런 쿡스태커의 답변 을 정말 좋아 합니다. 나는 그것에 대한 의견에 내 생각을 던지는 중에 있었지만 내 접근 방식은 너무 답답하여 여기에 떠나지 않는다고 생각합니다.

요약하면 공간의 특정 위치에 Coca-Cola 로고가 있는지 확인하는 알고리즘을 식별했습니다. 이제 임의의 방향과 임의의 스케일링 요소에 대해 코카콜라를 구별하기에 적합한 휴리스틱을 결정하려고합니다. , 광고판 , 광고 및 이 아이콘 로고와 관련된 Coca-Cola 도구를 포함하여 다른 개체와 . 문제 진술에서 이러한 추가 사례를 많이 언급하지는 않았지만 알고리즘 성공에 필수적이라고 생각합니다.

여기에 비밀은 무엇을 시각적 기능을 결정하는 캔이 기능은 캔 존재하지 않는 다른 콜라 제품에 존재하는 무엇, 부정적인 공간을 포함하거나. 이를 위해, 현재 최고 답변 은 병 뚜껑, 액체 또는 다른 유사한 시각적 휴리스틱의 존재에 의해 "병"이 식별되지 않은 경우에만 "캔"을 선택하기위한 기본 접근법을 제시한다.

문제는 이것이 분해된다는 것입니다. 예를 들어, 병은 비어 있고 뚜껑이 없어서 오탐 (false positive)으로 이어질 수 있습니다. 또는 추가 기능이 엉망 이 되어 부분적인 병 이되어 잘못된 탐지로 이어질 수 있습니다 . 말할 것도없이, 이것은 우아하지도 않고 우리의 목적에도 효과적이지 않습니다.

이를 위해 캔에 대한 가장 올바른 선택 기준은 다음과 같습니다.

  • 질문에서 스케치 한 객체 실루엣의 모양이 맞습니까? 그렇다면 +1.
  • 자연광 또는 인공 조명이 있다고 가정하면 알루미늄으로 만들어 졌는지 여부를 나타내는 크롬 윤곽선을 병에 감지합니까? 그렇다면 +1.
  • 광원에 비해 물체 의 반사 특성 이 올바른지 결정합니까 ( 설명 비디오 링크광원 감지 )? 그렇다면 +1.
  • 로고의 토폴로지 이미지 왜곡, 객체의 방향, 객체의 병치 (예 : 평면 표면)를 포함하여 객체를 캔으로 식별하는 객체에 대한 다른 속성을 결정할 수 있습니까? 테이블이나 다른 캔의 맥락에서), 당김 탭이 있습니까? 그렇다면 각각에 대해 +1입니다.

그러면 분류가 다음과 같이 보일 수 있습니다.

  • 각 후보 경기마다 코카콜라 로고가 감지되면 회색 테두리를 그립니다.
  • +2 이상 일치 할 때마다 빨간색 테두리를 그립니다.

이것은 사용자에게 감지 된 것을 시각적으로 강조 표시하여 맹 글링 캔으로 올바르게 감지 될 수있는 약한 양성을 강조합니다.

각 속성의 탐지는 시간과 공간의 복잡성이 매우 다르며 각 방법마다 http://dsp.stackexchange.com을 통한 빠른 통과 는 목적에 가장 정확하고 효율적인 알고리즘을 결정하는 데 합리적입니다. 여기서 의도는 순전히 간단하게 후보 탐지 공간의 작은 부분을 무효화하여 무언가가 캔 인지 감지하는 것입니다. 문제에 대한 가장 강력하거나 효과적인 해결책이 아니며, 이상적으로는 적절한 조치를 취해야 함 따라서.

그리고 해커 뉴스 게시를 축하합니다 ! 전체적으로, 이것은 그것이받은 홍보에 가치가있는 아주 훌륭한 질문입니다. :)


2
그것은 시도해 볼만한 가치가있는 흥미로운 접근법입니다. 문제에 대한 당신의 추론을 정말로 좋아합니다
Charles Menguy

이것은 내가 생각한 종류입니다. 특정 종류의 오 탐지를 배제하지 마십시오. 코크스 캔의 특징에 대한 더 많은 기능을 지배하십시오. 그러나 나는 궁금합니다 : 당신은 찌그러진 캔에 대해 무엇을합니까? 코카콜라를 밟아도 여전히 코크 스캔 일 수 있습니다. 그러나 더 이상 같은 모양이 아닙니다. 아니면 AI 완료 문제입니까?
Ian

41

모양을보고

캔 / 병의 빨간색 부분 모양을 한눈에 살펴보십시오. 병 레이블이 똑바로있는 동안 캔이 맨 위에서 약간 테이퍼되는 방식을 확인하십시오. 빨강 부분의 너비와 길이의 길이를 비교하여이 두 가지를 구별 할 수 있습니다.

하이라이트를보고

병과 캔을 구별하는 한 가지 방법은 재료입니다. 병은 플라스틱으로 만들어졌지만 캔은 알루미늄 금속으로 만들어졌습니다. 조명이 충분한 상황에서 스페 큘러를 보는 것이 캔 레이블에서 병 레이블을 알리는 한 가지 방법입니다.

내가 알 수있는 한, 인간이 두 가지 유형의 레이블 사이의 차이점을 말하는 방법입니다. 조명 조건이 열악한 경우 두 가지를 구별하는 데 약간의 불확실성이 있습니다. 이 경우 투명 / 반투명 병 자체의 존재를 감지 할 수 있어야합니다.


나는 그 아이디어를 좋아하지만 정말로 좋은 조명 조건이 필요할 것 같습니다. 예를 들어 캔과 병이 모두있는 예제 이미지에서 이는 구분하기가 다소 어려워 보입니다.
Charles Menguy

귀하의 예에서 플라스틱 라벨의 반사도가 캔의 매우 밝은 점보다 훨씬 더 확산되어 있는지 확인하십시오. 그렇게 말할 수 있습니다.
tskuzzy

이 경우 알고리즘의 반사성을 캡처하기 위해 어떤 색 공간 표현을 사용 하시겠습니까? 이것은 RGB 또는 HSV에 도착하는 것은 매우 힘든 것 같다
찰스 Menguy

3
광원이 캔 뒤에 있으면 어떻게합니까? 나는 당신이 하이라이트를 보지 못할 것이라고 생각합니다.
Rui Marques

37

Zdenek Kalal의 프레데터 추적기를 살펴보십시오 . 약간의 훈련이 필요하지만 추적 된 물체가 다른 방향과 스케일로 어떻게 보이는지 적극적으로 배울 수 있습니다!

소스 코드는 그의 사이트에서 구할 수 있습니다. 그것은에서의 MATLAB , 그러나 아마 이미 커뮤니티 회원에 의해 수행 자바 구현이있다. C #에서 TLD의 추적기 부분을 성공적으로 다시 구현했습니다. 내가 올바르게 기억한다면, TLD는 Ferns를 키포인트 탐지기로 사용하고 있습니다. 트래커가 객체를 잃어버린 경우 SURF 또는 SIFT (@stacker에서 이미 제안 함)를 대신 사용하여 객체를 다시 얻습니다. 트래커의 피드백을 통해 시간이 지남에 따라 매우 높은 정밀도로 객체를 다시 획득 할 수있는 동적 체프 / 서핑 템플릿 목록을 시간에 따라 쉽게 구축 할 수 있습니다.

트래커의 C # 구현에 관심이 있으시면 언제든지 문의하십시오.


흥미로운 링크에 감사드립니다. 훈련과 관련하여 합리적인 결과를 달성하기에 적합한 훈련 세트의 규모는 얼마입니까? C #에서도 구현이 있다면 매우 도움이 될 것입니다!
Charles Menguy

TLD를 조사하는 동안 다른 사용자가 C # 구현을 찾고 있음을 발견했습니다. Github에서 작업하지 않는 이유가 있습니까? stackoverflow.com/questions/29436719/…
spillner

2
NB 년, 나중에, 링크는 이제 죽었습니다
J Evans

33

제약 조건 중 하나가 아닌 카메라에만 국한되지 않으면 Xbox Kinect 와 같은 범위 센서를 사용하여 이동할 수 있습니다 . 이를 통해 이미지의 깊이 및 색상 기반 일치 분할을 수행 할 수 있습니다. 이를 통해 이미지에서 객체를 더 빨리 분리 할 수 ​​있습니다. 그런 다음 ICP 일치 또는 유사한 기술을 사용하여 외곽선 또는 색상 대신 캔의 모양과 일치시킬 수 있으며 원통형 인 경우 대상의 이전 3D 스캔이있는 경우 모든 방향에 유효한 옵션이 될 수 있습니다. 이러한 기술은 속도 문제를 해결해야하는 특정 목적으로 사용될 때 특히 빠릅니다.

또한 정확성이나 속도가 반드시 필요한 것은 아니지만 재미를 위해 색조 세그먼트 이미지에서 훈련 된 신경망을 사용하여 캔 모양을 식별 할 수 있습니다. 이들은 매우 빠르며 종종 최대 80 / 90 % 정확도 일 수 있습니다. 각 이미지에서 캔을 수동으로 식별해야하므로 교육은 약간의 시간이 걸립니다.


3
실제로 나는 게시물에서 그것을 설명하지 않았지만,이 과제를 위해 대략 30 개의 이미지 세트가 주어졌으며 설명 된대로 다양한 상황에서 모든 이미지를 일치시키는 알고리즘을 수행해야했습니다. 물론 일부 이미지는 결국 알고리즘을 테스트하기 위해 개최되었습니다. 그러나 Kinect 센서의 아이디어가 마음에 들며이 주제에 대해 더 자세히 읽고 싶습니다!
Charles Menguy

만족스러운 결과를 얻기 위해 신경망을 갖춘 훈련 세트의 크기는 대략 얼마입니까? 이 방법의 좋은 점은 거의 모든 것과 일치하는 템플릿이 하나만 필요하다는 것입니다.
Charles Menguy

2
이미지 세트가 사전 정의되어 제한되어 있다면 하드 코어 완벽한 결과물을 얻을 수 있습니다.)
sne11ius

그래, 내가 데이터 세트를 훈련 시키면 알고리즘을 실행할 것입니다. 완벽한 결과를 얻을 것입니다 :) 그러나 예를 들어이 과제의 경우, 프로그램은 마지막으로 교사가 일련의 일련의 이미지를 테스트했습니다 . 교육 데이터에 비해 견고하고 적합하지 않은 작업을하고 싶습니다.
Charles Menguy

훈련 세트의 수는 다양하지만 몇 가지 사항에주의해야합니다. 훈련하지 마십시오. 정확도가 어떻게 진행되는지 보여주는 테스트 세트를 원할 것입니다. 또한 트레이닝 세트의 수는 사용할 레이어 수에 따라 다릅니다.
환상적인 Mr Fox

24

빨간색 사각형을 감지합니다 : RGB-> HSV, 필터 빨간색-> 이진 이미지, 닫기 (매트랩에서 알려진 확장 후 침식 imclose)

그런 다음 가장 큰 사각형부터 작은 사각형까지 살펴보십시오. 알려진 위치 / 규모에서 더 작은 사각형을 가진 사각형은 모두 제거 할 수 있습니다 (병 비율이 일정하다고 가정하면 작은 사각형은 병 뚜껑이됩니다).

그러면 빨간색 사각형이 남게되며 로고가 빨간색 사각형인지 콜라인지 알 수 있도록 로고를 감지해야합니다. OCR과 비슷하지만 알려진 로고가 있습니까?


2
DSP가 옮겨 졌을 때 짧은 시간에 DSP에서 논의 된 것처럼 일부 병에는 플러그가 없거나 플러그가 부분적으로 숨겨져있을 수 있습니다.
Charles Menguy

22

이것은 매우 순진한 아이디어 일 수도 있고 전혀 작동하지 않을 수도 있지만 모든 코크스 캔의 크기는 고정되어 있습니다. 따라서 동일한 이미지에 캔과 병이 모두 포함되어 있으면 크기를 고려하여 구분할 수 있습니다 (병이 더 커짐). 이제 깊이가 없어서 (즉, 3D 매핑에서 2D 매핑으로) 병이 축소되어 나타날 수 있으며 크기 차이가 없을 수 있습니다. 스테레오 이미징을 사용하여 일부 깊이 정보 를 복구 한 다음 원래 크기를 복구 할 수 있습니다.


3
실제로 아니오 : 크기 또는 방향의 제약이 없으며 (또는 방향이지만 실제로 처리하지 않았습니다) 백그라운드에서 병을 멀리, 전경에서 캔을 가질 수 있으며 캔은 더 커질 수 있습니다 병보다.
Charles Menguy

또한 너비 대 높이 비율이 병과 캔과 매우 유사하다는 것을 확인 했으므로 실제로는 옵션이 아닙니다.
Charles Menguy

레이블 비율 (상표명)은 동일합니다. 따라서 (더 큰) 병이 그림에서 약간 더 떨어져 있으면 크기가 캔의 크기와 정확히 동일합니다.
littleadv

3
좀 더 설명하기 위해. 캔이 z = 0에 있고 병이 z = -100에 있다고 가정하십시오. 병이 훨씬 뒤에 있기 때문에 더 작아 보입니다. 그러나 병이 z = -100이고 z = 0 일 수 있다는 것을 알고 있다면 캔 / 병의 예상 크기를 모두 z = 0으로 변환하면 계산할 수 있습니다. 이제는 깊이가 같으므로 크기에 따라 결정을 내릴 수 있습니다.
Sharad

2
이것은 답변이 아닌 의견 일 뿐이지 만, 120 표로 된 답변으로서의 의견보다 답변에 훨씬 더 가깝습니다.
Fattie

22

흠, 나는 실제로 내가 무언가에 있다고 생각 합니다 (이것은 지금까지 가장 흥미로운 질문과 같습니다. 따라서 "완벽한"답을 찾기 위해 계속 노력하지 않는 것은 부끄러운 일입니다.) .

로고를 찾으면 문제가 절반으로 해결됩니다. 그런 다음 로고 주위 의 차이점 만 파악하면됩니다 . 또한 가능한 한 적은 노력을 기울이고 싶습니다. 나는 이것이 실제로 쉬운 부분이라고 생각합니다 ...

무엇 입니다 로고 주위에? 캔의 경우 조명의 영향에도 불구하고 기본 색상의 변화가없는 금속을 볼 수 있습니다. 라벨의 각도를 알고 있다면 바로 위에있는 것을 알 수 있으므로 다음과 같은 차이점을 살펴 보겠습니다.

여기에서 로고 위와 아래의 색상은 완전히 어둡고 일관성이 있습니다. 그 점에서 비교적 쉽습니다.

여기 위와 아래는 가벼우면서도 색상이 일정합니다. 그것은 은색이며, 은색 금속은 일반적으로 은색뿐만 아니라 실제로는 매우 드문 것 같습니다. 또한 얇은 슬라이더로 이미 식별 된 빨간색에 충분히 가까우므로 전체 길이에 대한 모양을 추적하여 캔의 금속 링으로 간주 할 수있는 비율을 계산할 수 있습니다. 실제로, 캔을 따라 어느 부분이든 그 부분을 알기 위해서는 그 부분의 작은 부분 만 필요하지만, 그 뒤에 금속이 든 빈 병이 아닌 균형을 찾아야합니다.

그리고 마지막으로 까다로운 것. 그러나 우리가 빨간 포장지 바로 위 (아래)에서 볼 수있는 것으로 만 가면 그렇게 까다 롭지 않습니다. 투명하므로 뒤에있는 모든 것을 보여줍니다. 그 뒤에있는 것은 캔의 은색 원형 금속만큼 색상이 일정하지 않을 수 있기 때문에 좋습니다. 그 뒤에는 여러 가지가있을 수 있습니다. 빈 병 (또는 투명한 액체로 채워진 병)이거나 일관된 색상으로 액체가 채워져 있거나 병이 단순히 앞에 있음을 의미 할 수 있습니다 단색. 우리는 상단과 하단에 가장 가까운 것을 사용하고 있으며 올바른 색상이 올바른 장소에있을 가능성은 상대적으로 적습니다. 우리는 그것이 병이라는 것을 알고 있습니다. 왜냐하면 캔의 핵심적인 시각적 요소가 없기 때문입니다.

(마지막으로 큰 코카콜라 병을 찾을 수있는 것이 가장 좋았습니다. 흥미롭게도 캡과 링은 노란색으로 캡의 발적에 의존하지 않아야 함을 나타냅니다)

드문 경우에 플라스틱의 추상화 후에도 비슷한 은의 그늘이 병 뒤에 있거나 병이 어떻게 같은 은색 액체의 액체로 채워져 있는지, 우리는 대략적으로 내가 언급했듯이 은의 모양-원형이며 캔의 모양을 따릅니다. 그러나 이미지 처리에 대한 지식이 부족하더라도 느리게 들립니다. 더 좋은 방법 은, 로고 측면 을 한 번 확인 하여 동일한 실버 색상이 없는지 확인하여 이를 추론 해 보지 않겠습니까? 아, 그러나 캔 뒤에 같은 그늘이 있다면 어떨까요? 그런 다음 캔의 상단과 하단을 다시 보면서 모양에 더 많은주의를 기울여야합니다.

이 모든 것이 얼마나 완벽한 지에 따라 매우 느릴 수 있지만 기본 개념은 가장 쉽고 가장 가까운 것을 먼저 확인하는 것입니다. 다른 요소의 모양을 만들기 위해 노력하기 전에 이미 일치하는 모양 (어쨌든 가장 사소한 부분 인 것) 주위의 색상 차이로 이동하십시오. 그것을 나열하려면 다음과 같이하십시오.

  • 주요 매력을 찾으십시오 (빨간색 로고 배경 및 방향에 대한 로고 자체는 가능하지만 캔이 꺼진 경우 빨간색에만 집중해야 함)
  • 매우 독특한 적색을 통해 모양과 방향을 다시 확인하십시오.
  • 모양 주위의 색상을 확인하십시오 (빠르고 고통스럽지 않기 때문에)
  • 마지막으로, 필요한 경우 올바른 진원도에 대한 주요 매력 주변의 색상 모양을 확인하십시오.

당신이 이것을 할 수 없다면, 그것은 아마도 캔의 상단과 하단이 덮혀 있음을 의미하며, 인간이 캔과 병을 확실하게 구별하기 위해 사용할 수 있었던 유일한 가능성은 폐색과 반사입니다 처리하기 가 훨씬 어려울 수 있습니다. 그러나 더 나아가서 다른 답변에서 언급 한 반투명 스캐닝 기술을 사용하여 캔 / 병의 각도를 따라 더 많은 병과 같은 특성을 확인할 수 있습니다.

흥미로운 추가 악몽에는 병 뒤에 금속이 레이블 위와 아래에 표시되는 거리에 편리하게 병 뒤에 앉아있는 캔이 포함될 수 있습니다. 이는 빨간색의 전체 길이를 따라 스캔하는 한 여전히 실패합니다. 레이블-실수로 캔을 포함하여 실제로 병을 감지하는 것을 고려하는 것과는 달리, 가능한 캔을 감지하지 못하기 때문에 실제로 더 큰 문제입니다. 이 경우 유리가 반쯤 비어 있습니다!


면책 조항으로, 나는이 질문 이외의 이미지 처리에 대한 경험이 없거나 생각하지 못했지만 너무 흥미로워 서 그것에 대해 깊이 생각하게하고 다른 모든 대답을 읽은 후에는 이것이 아마도 가장 쉬운 가장 효율적인 방법은 완료하세요. 개인적으로, 나는 이것을 프로그래밍하는 것에 대해 실제로 생각할 필요가 없다는 것이 기쁘다 !

편집하다

MS 페인트에서 캔의 잘못된 그리기 또한, 제가 MS Paint에서 한이 그림을보십시오. 그것은 절대적으로 끔찍하고 불완전하지만, 모양과 색상만을 고려하면, 아마도 무엇이 될지 추측 할 수 있습니다. 본질적으로, 이것들은 스캔을 귀찮게하는 데 필요한 유일한 것입니다. 매우 독특한 모양과 색상의 조합을 가까이서 살펴보면 다른 무엇을 할 수 있을까요? 내가 칠하지 않은 비트, 흰색 배경은 "일관되지 않은 것"으로 간주해야합니다. 배경이 투명하면 거의 다른 이미지로 넘어가도 여전히 볼 수 있습니다.


10
적색의 특정 음영은 대부분 주관적이며 조명 고려 사항 및 화이트 밸런스에 의해 크게 영향을받습니다. 그것들이 얼마나 많이 변할 수 있는지에 놀랄 것입니다. 예를 들어,이 바둑판 환상 을 고려하십시오 .
Octopus

2
@Octopus가 게시 한 링크 업데이트 : persci.mit.edu/gallery/checkershadow
Hat

지각 착각은 웹캠이 보는 것, 즉 코드가 얻는 것에 영향을 미치지 않으며 인간의 눈이 뇌를 어떻게 도와 주는지에만 영향을 미칩니다.
바니

17

OpenCV에 대해 잘 모르지만 문제를 논리적으로 살펴보면 병을 구별 할 수 있고 Coca Cola와 같이 찾고있는 이미지를 변경하여 캔을 구별 할 수 있다고 생각합니다. 코카콜라의 상단에 은색 라이닝이있을 수 있고 병의 경우에는 은색 라이닝이 없을 수 있으므로 캔의 상단 부분까지 통합해야합니다.

그러나이 알고리즘은 캔의 상단이 숨겨져있는 경우에는 실패하지만 사람의 경우에도 두 사람을 구별 할 수 없습니다 (병의 코카콜라 부분 만 볼 수있는 경우)


1
나는 같은 생각을 가지고 있었지만 캔 위의 은색 안감은 그림의 캔 각도에 따라 크게 변한다고 생각합니다. 직선 또는 원이 될 수 있습니다. 아마 둘 다 참고로 사용할 수 있을까요?
Alexis Dufrenoy

15

나는 도전을 좋아하고 문제를 해결하는 답을주고 싶었다고 생각합니다.

  1. 로고의 특징 (키포인트, SIFT, SURF와 같은 설명자) 추출
  2. 로고의 모델 이미지와 포인트를 일치시킵니다 (Brute Force와 같은 Matcher 사용)
  3. 강체 좌표 계산 (PnP 문제-SolvePnP)
  4. 강체에 따른 캡 위치 추정
  5. 역 투영을 수행하고 병 뚜껑의 이미지 픽셀 위치 (ROI)를 계산합니다 (카메라의 고유 매개 변수가 있다고 가정).
  6. 뚜껑이 있는지 여부를 방법으로 확인하십시오. 있다면이 병입니다

캡 감지는 또 다른 문제입니다. 복잡하거나 단순 할 수 있습니다. 내가 당신이라면, 간단한 결정을 위해 ROI에서 컬러 히스토그램을 점검 할 것입니다.

내가 틀렸다면 피드백을주세요. 감사.


13

이 질문에 대답하는 데 몇 년이 늦었습니다. 지난 5 년 동안 CNN이 최첨단 기술로 한계를 뛰어 넘어 지금 OpenCV를 사용하여이 작업을 수행하지 않을 것입니다! ( 난 당신이 특별히 OpenCV의 질문에 기능 원 알고 내가 OpenCV의 특징에 비해 큰 폭으로이 문제를 에이스 것 같은 빠른-RCNNs, 욜로, SSD 등과 같은 물체 검출 알고리즘을 느낀다). 6 년 후이 문제를 해결하려면 Faster-RCNN을 사용 하십시오 .


5
OP는 30 개의 고해상도 이미지가 있으며 이는 아마도 ConvNet 교육을위한 최상의 시나리오는 아닐 것이라고 말했다. 그것들은 너무 적거나 (증가 된), 고해상도 부분은 ConvNet을 파괴 할 것입니다.
Kostas Mouratidis 2014 년

11

주제가 아닌지에 관계없이 귀하의 질문을 좋아합니다. : P

재미있는 옆으로; 로봇 공학과 컴퓨터 비전을 다루는 학위를 마쳤습니다. 학기 동안의 프로젝트는 여러분이 묘사 한 프로젝트와 엄청나게 유사했습니다.

Xbox Kinect를 사용하여 다양한 조명 및 환경 조건에서 모든 방향의 코크스 병 및 캔을 감지하는 로봇을 개발해야했습니다. 우리의 솔루션은 Hue 원형 변환과 함께 Hue 채널에서 대역 통과 필터를 사용하는 것과 관련이 있습니다. 우리는 환경을 약간 제한 할 수 있었으며 (로봇과 Kinect 센서의 위치와 방법을 선택할 수 있음) 그렇지 않은 경우 SIFT 또는 SURF 변환을 사용하려고했습니다.

당신은 주제에 대한 내 블로그 게시물에서 우리의 접근 방식에 대해 읽을 수 있습니다 :)


2
흥미로운 프로젝트이지만 매우 구체적인 설정에만 적용됩니다.
Rui Marques

10

객체를 인식하는 데 사용되는 많은 색상 설명자가 있으며 아래의 용지는 많은 것을 비교합니다. SIFT 또는 SURF와 결합 될 때 특히 강력합니다. SURF 또는 SIFT만으로는 코카콜라 이미지에서 그다지 흥미로운 점을 인식하지 못하기 때문에 그다지 유용하지 않습니다. 색상 정보가 필요합니다. 프로젝트에서 SURF와 함께 BIC (테두리 / 인테리어 픽셀 분류)를 사용하고 객체를 인식하는 데 효과적이었습니다.

웹 이미지 검색을위한 색상 설명자 : 비교 연구


10

딥 러닝

콜라 캔이 들어있는 수백 개 이상의 이미지를 모으고 그 주위의 경계 상자에 긍정적 인 클래스로 주석을 달고 콜라 병 및 기타 콜라 제품에는 부정적 클래스뿐만 아니라 임의의 물건으로 분류합니다.

매우 큰 데이터 세트를 수집하지 않는 한 작은 데이터 세트에 딥 러닝 기능을 사용하는 트릭을 수행하십시오. 심부 신경망과 SVM (Support Vector Machines)의 조합을 사용하는 것이 이상적입니다.

신경망의 의사 결정 (최종) 레이어를 사용하여 분류하는 대신 이전에 훈련 된 딥 러닝 모델 (예 : GoogleNet)에 이미지를 공급 한 후에는 분류자를 훈련시키는 기능으로 이전 레이어의 데이터를 사용하십시오.

OpenCV 및 Google Net : http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

OpenCV 및 SVM : http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html


9

경험을 통해 유기적으로 분류 정확도를 배우고 향상시키는 프로그램이 필요합니다.

나는 딥 러닝을 제안 할 것입니다. 딥 러닝으로 이것은 사소한 문제가됩니다.

Tensorflow에서 시작 v3 모델을 재교육 할 수 있습니다.

새 범주에 대한 시작의 최종 계층을 재교육하는 방법 .

이 경우 객체를 코카콜라로 분류 할 수있는 컨볼 루션 신경망을 훈련하게됩니다.


2
핫도그 또는 핫도그?
YellowPillow

6

이 모든 훌륭한 솔루션의 대안으로 자체 분류기를 훈련시키고 응용 프로그램을 오류에 강력하게 만들 수 있습니다. 예를 들어 Haar Training을 사용하면 대상의 긍정적이고 부정적인 이미지를 많이 얻을 수 있습니다.

캔만 추출하는 것이 유용하며 투명한 물체의 감지와 결합 될 수 있습니다.


3

MVTec의 HALCON 이라는 컴퓨터 비전 패키지가 있습니다 의 데모를 통해 알고리즘 아이디어를 얻을 수 있습니다. 데모 모드에서 실행 한 다음 코드에서 연산자를보고 기존 OpenCV 연산자에서이를 구현하는 방법을 볼 수있는 문제와 유사한 예제가 많이 있습니다.

이 패키지를 사용하여 이와 같은 문제에 대한 복잡한 알고리즘을 신속하게 프로토 타입 한 다음 기존 OpenCV 기능을 사용하여 구현하는 방법을 찾았습니다. 특히 귀하의 경우 findCscaled_shape_model 연산자에 포함 된 기능을 OpenCV에서 구현하려고 시도 할 수 있습니다. 일부 운영자는 OpenCV에서 유사한 작업을 수행하는 방법을 찾는 데 도움이되는 알고리즘 구현에 관한 과학 논문을 지적합니다. 도움이 되었기를 바랍니다...


0

실시간에 관심이 있다면, 사전 처리 필터를 추가하여 무거운 물건으로 스캔 할 대상을 결정해야합니다. 코카콜라 일 가능성이 높은 것을 스캔 할 수있게 해주는 빠르고 빠른 실시간 전처리 필터는 다음과 같은 경우입니다. sqrt(pow(red,2) + pow(blue,2) + pow(green,2))코카콜라 캔 과 는 거리가 멀다. 매우 엄격한 색 공차로 시작하여보다 관대 한 색 공차로 나아갑니다. 그런 다음 로봇이 현재 프레임을 처리하기 위해 할당 된 시간이 부족하면 현재 찾은 병을 목적에 맞게 사용합니다. RGB 색상을 sqrt(pow(red,2) + pow(blue,2) + pow(green,2))올바르게 조정하려면 RGB 색상을 조정 해야합니다.

또한 이것은 정말 바보처럼 보이지만 -oFastC 코드를 컴파일 할 때 컴파일러 최적화를 설정 했습니까?


0

어쩌면 너무 오래 늦었지만 시도하는 이론.

병 / 캔의 전체 치수에 대한 빨간색 로고 영역의 경계 사각형의 비율이 다릅니다. 캔의 경우, 1 : 1이어야하지만 병의 경우 (캡이 있거나없는) 다를 수 있습니다. 이를 통해 두 가지를 쉽게 구별 할 수 있습니다.

업데이트 : 로고 영역의 수평 곡률은 각각의 크기 차이로 인해 캔과 병에서 다릅니다. 로봇이 캔 / 병을 들어 올려 그립을 결정하는 경우 특히 유용합니다.


-1

내가 찾게 될 첫 번째 것은 RED 같은 이미지입니다. 이미지에서 적목 현상을 감지 할 때 감지해야 할 특정 색상 범위가 있습니다. 주변 영역을 고려한 주변 특성과 다른 눈과의 거리와 같은 거리가 있습니다. 실제로 이미지에서 볼 수 있습니다.

1 : 첫 번째 특징은 색상이고 빨간색은 매우 지배적입니다. Coca Cola Red를 감지 한 후 몇 가지 관심 항목이 있습니다. 1A :이 빨간색 영역의 크기 (진정한 캔을 결정하기에 충분한 양입니까-10 픽셀이면 충분하지 않음), 1B : 포함합니까? 라벨의 색상- "Coca-Cola"또는 웨이브. 1B1 : 레이블 일 가능성이 높다고 생각할만큼 충분한가?

항목 1은 일종의 지름길-이미지에 존재하지 않는 전처리-계속 진행합니다.

그렇다면이 경우 이미지의 해당 세그먼트를 활용하고 문제의 영역을 조금 더 축소하기 시작할 수 있습니다. 기본적으로 주변 영역 / 가장자리를보십시오 ...

2 : 1에서 위의 이미지 영역 ID가 주어진 경우-해당 항목의 주변 지점 [가장자리]를 확인하십시오. A : 캔 상단 또는 하단-은으로 보이는 것이 있습니까? B : 병이 투명하게 보일 수 있지만 유리 테이블도 유리 테이블 / 선반 또는 투명 영역이있을 수 있습니다. 병에는 빨간색 뚜껑이있을 수 있지만 그렇지 않을 수도 있지만 병 상단 / 나사 나사 모양이나 뚜껑이 있어야합니다. C : 이것이 A와 B에 실패하더라도 여전히 부분 캔일 수 있습니다. 부분 병 / 부분의 모양이 동일 해 보일 수 있기 때문에 부분 부분 일 때 더 복잡합니다. 작은 병은 크기가 비슷할 수 있습니다.

3 : 위의 분석 후 나는 글자와 웨이브 로고를 볼 것입니다. 왜냐하면 단어의 일부 문자에 대한 검색 방향을 지정할 수 있기 때문입니다. 웨이브가 특정 지점에서 텍스트 (거리와 현명한)로 정렬되어 그 확률을 검색하고 x 거리에서 웨이브의 해당 지점에 어떤 문자가 있어야하는지 알 수 있습니다.


-9

이것은 내가 일한 오래된 프로젝트입니다. MAP 이미지는 자바 스크립트와 함께 사용하기가 매우 쉽습니다. 나는 당신에게 물건을 제공하고, 당신은 그것을 읽고 사용법을 알고 있습니다. MAP 이미지를 사용하기 위해 JQuery 및 기타 시스템이 필요하지 않습니다.

    //Copyright Cherif yahiaoui, by ELEBAN.FR

//variables de flottement.
var myInstOne = null;
var globalize = null;

var eleban_preload_images = function (name, imgs, url){
try{
    var oThis = this;
    this.images = new Array();
    this.imageshover = new Array();
    this.imagesNames = new Array(imgs.split(";"));


        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i] = new Image();
            this.imageshover[i] = new Image();
        }

    this.url = url;

    this.GetAbsoluteurl = function () {

    var img = new Image(); img.src = url;
    url = img.src; img = null; 
        this.url = url; 

    };

    this.Preload = function () {

        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i].src = this.url+("btn-"+this.imagesNames[0][i]+".png");
            this.imageshover[i].src = this.url+("btn-"+this.imagesNames[0][i]+"-hover.png");
        }

    };
    this.GetAbsoluteurl();
    this.Preload();
}
finally {return;}
}

var g_preloaderhover = new eleban_preload_images("loaderhover","menu;malette;reservation;cabine;facebook;map;amis","./images/");


//variable arret flottement
var g_stopflo = false;

var myObjfloater = function(name, idname, itop, differ ) {
var oThis = this; // création d'une référence vers l'objet courant
this.name = name;
this.id =idname;
this.xstep= 0.3;
this.itime = 30;
this.obj = null;
this.y = itop;
this.yadd = 0;
this.up = true;
this.pause = false;
this.differ = differ;
this.coordsimage = null;
this.objimg = null;
this.initimages = false;
this.compteur = 0;
this.over = false;
this.timeoutstop = null;
try{
this.initimage = function(){
var img = this.obj.getElementsByTagName('img')[0];
this.coordsimage = new Array(img.width, img.height);
this.objimg = img;
this.initimages = true;
};


this.myMethod = function() {
if(!g_stopflo){
    if(this.differ != 0){ 
this.differ=this.differ-0.1; 
}else{

if(this.obj){
if(this.over == false){
    this.yadd=this.yadd+0.1; this.itime = this.itime + 10;
this.obj.style.visibility = "hidden";
this.y = ((this.up)? this.y - this.yadd : this.y + this.yadd);
this.obj.style.marginTop = this.y +"%" ;
this.obj.style.visibility = "visible";

if (this.yadd > this.xstep){ 
    this.up = (this.up)? false : true;
    this.yadd = -0.1; this.itime=180;
}
}
}else{
    if (document){
        if(document.getElementById) {
         this.obj = document.getElementById(this.id); 
        //this.y = this.obj.offsetTop;
        }else{
        if(document.getElementByTagName) { this.obj = document.getElementByTagName(this.id); this.y = this.obj.offsetTop;}
        }

    }
}
}
this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}    
};

this.callDelayed = function() {
    // utilisation de la référence vers l'objet
if(!g_stopflo){
    this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}
};
}
finally {return;}
};

// special creation des zones AREA
function eleban_createallarea(){
try{
var measur = new Array("w", "h");
measur["w"] = new Array(330,570,185,300,115,390,225);
measur["h"] = new Array(460,570,295,450,100,190,115);
var ititle = new Array("Voir les menus  et nos suggestions","Repas &agrave; emporter","R&eacute;servation d&rsquo;une table","Nous contacter","Nous rejoindre sur FaceBook","Calculer votre trajet","liste des amis");
var ihref = new Array("menus.html","emporter.html","reservation.html","contact.html","likebox.html","google.html","amis.html");
var b_map = new Array(0,1,2,3,4,5,6);
b_map[0] = "71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38";
b_map[1] = "66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92";
b_map[2] = "19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90";
b_map[3] = "60,0,216,1,226,20,225,403,168,421,42,410,45,10";
b_map[4] = "31,7,72,10,82,18,88,45,88,71,76,81,29,80,17,68,16,18";
b_map[5] = "91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94";
b_map[6] = "6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65";

if (document.getElementById){
for (var i=0; i<b_map.length;i++){
var obj = document.getElementById("pc_menu"+i);
    if(obj){
    var ct = '<img class=\"pc_menu\" src=\"'+g_preloaderhover.images[i].src+'\" alt=\"\" width=\"'+measur["w"][i]+'\" height=\"'+measur["h"][i]+'\" usemap=\"#MAP_INDEX'+i+'\" \/>';
    ct+='<map name=\"MAP_INDEX'+i+'\">';
    ct+='<area shape=\"poly\" coords=\"'+b_map[i]+'\" title=\"'+ititle[i]+'\" href=\"'+ihref[i]+'\" \/>';
    ct+='<\/map>';
    obj.innerHTML = ct;
    }
}
}
}
finally {return;}
}

//preload, creation et gestion de tous les evenements


var image_resizer = function(g_layer){


    b_org_elm = new Array("w",  "h");
    b_org_elm["w"] = new Array(330,570,185,300,115,390,225);
    b_org_elm["h"] = new Array(460,570,295,450,100,190,115);

    b_map = new Array(0,1,2,3,4,5,6);
    b_map[0] = new Array(71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38);
    b_map[1] = new Array(66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92);
    b_map[2] = new Array(19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90);
    b_map[3] = new Array(60,0,216,1,226,20,225,403,168,421,42,410,45,10);
    b_map[4] = new Array(31,6,70,10,78,18,84,23,88,44,88,70,78,80,75,81,33,82,23,76,18,69,16,22,21,13);
    b_map[5] = new Array(91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94);
    b_map[6] = new Array(6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65);


    b_layer = g_layer;

//gere mouseover
    this.mouseover = function(e){
        if (!e) var e = window.event;
        var tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                var divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.imageshover[ii].src;
                                }
                        }
                    }
                }
            }
    };

//gere mouseout
    this.mouseout = function(e){
        if (!e) var e = window.event;
        tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.images[ii].src;
                                }
                        }
                    }
                }
            }
    };

//ajout evenements entree sortie à la page web lors du chargement de la page
    this.init = function () {

        for(var i=0; i<b_org_elm["w"].length;i++){
            w = document.getElementById("pc_menu"+i).offsetWidth;
            h = document.getElementById("pc_menu"+i).offsetHeight;

            xa = w/parseFloat(b_org_elm["w"][i]);
            ya = h/parseFloat(b_org_elm["h"][i]);

            area = document.getElementById("pc_menu"+i).getElementsByTagName('area')[0];

            b_map2 = area.coords.split(",");
            yswitch = true;
                for(m=0; m<b_map2.length;m++){
                b_map2[m] = Math.round(parseFloat(b_map[i][m]) * ((yswitch)? xa: ya));
                yswitch = (yswitch)? false :  true;
                }
            area.coords = b_map2.join(',');
        }
    }; 


    this.resize = function () {
    clearTimeout(myInstOne.timeoutstop);
    g_stopflo=true;

    globalize.init();
    g_stopflo=false;
    myInstOne.obj = null;
    myInstOne.callDelayed();
    };


    nar = document.getElementsByTagName('area').length;

        for(var i=0; i<nar;i++){
            var elem = document.getElementsByTagName('area')[i];
            if (elem.addEventListener){
                    elem.addEventListener("onmouseover",this.mouseover,true);
                elem.addEventListener("onmouseout",this.mouseout,true);
            }else if (elem.attachEvent) {
                    elem.attachEvent("onmouseover", this.mouseover);
                    elem.attachEvent("onmouseout", this.mouseout);
            }else{
                    elem["onmouseover"] = this.mouseover;
                    elem["onmouseout"] = this.mouseout;
            }
        }

            window.onresize = this.resize;
        window.onmouseover = this.mouseover;
        window.onmouseout = this.mouseout;
}


//permet de temporiser et éviter les erreurs de chargement des objets
function temporise_Init(Lastdiv){
if(document.getElementById){
    if(document.getElementById(Lastdiv)){

    eleban_createallarea();

    myInstOne = new myObjfloater('b_menumap11', 'pc_menu1', 1, 0);

    globalize = new image_resizer(document.getElementById('pc_redim'));
    globalize.init();
        globalize.resize();



    }else{
    setTimeout(temporise_Init(Lastdiv), 30);
    }
}
}


window.onload = function () {
temporise_Init("pc_bandeau");
}

3
이것은 무엇을 하는가?
user8408080
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.