양쪽 이전 판이전 판다음 판 | 이전 판 |
project:detectsponsor [2013/07/08 08:44] – [결과 분석] ::1 | project:detectsponsor [2014/10/09 21:24] (현재) – 바깥 편집 127.0.0.1 |
---|
| |
$ convert -threshold 50% input.png | $ convert -threshold 50% input.png |
| |
'threshold가 뭐야?' 라고 궁금해 하실 분들이 있을 지 모르겠습니다. Threshold란 사전적 의미 그대로는 '한계점, 기준치, 문턱'입니다. "어떤 값이 기준치를 넘겼다, 넘기지 못했다"라고 말할 때의 그 '기준치'를 말합니다. (이미지 출처: http://www.svi.nl/SeedAndThreshold) | 'threshold가 뭐야?' 라고 궁금해 하실 분들이 있을 지 모르겠습니다. Threshold란 사전적 의미 그대로는 '한계점, 기준치, 문턱'입니다. "어떤 값이 기준치를 넘겼다, 넘기지 못했다"라고 말할 때의 그 '기준치'를 말합니다. (이미지 출처: http://www.svi.nl/SeedAndThreshold) |
{{ http://www.svi.nl/wikiimg/SeedAndThreshold_02.png?nolink | threshold }} | {{ http://www.svi.nl/wikiimg/SeedAndThreshold_02.png?nolink | threshold }} |
| |
convert는 입력된 그림파일의 픽셀을 일일이 검사합니다. 보통 픽셀은 보통 0~255의 단계값을 가집니다. 0이면 완전히 검은색, 255면 완전히 밝은 흰색입니다. 위 convert 명령의 예제는 그림의 펙셀에서 밝기 값이 50% 이상인 값은 100% 값을 가지고, 그렇지 못하면 0으로 만들라는 뜻입니다. 보다 알기 쉽게 예를 들어 보도록 하지요 5개의 픽셀이 있습니다. 각 픽셀은 다음과 같은 밝기를 가집니다. | convert는 입력된 그림파일의 픽셀을 일일이 검사합니다. 보통 픽셀은 보통 0~255의 단계값을 가집니다. 0이면 완전히 검은색, 255면 완전히 밝은 흰색입니다. 위 convert 명령의 예제는 그림의 펙셀에서 밝기 값이 50% 이상인 값은 100% 값을 가지고, 그렇지 못하면 0으로 만들라는 뜻입니다. 보다 알기 쉽게 예를 들어 보도록 하지요 5개의 픽셀이 있습니다. 각 픽셀은 다음과 같은 밝기를 가집니다. |
60, 30, 48, 40, 90 | 160, 120, 48, 140, 230 |
다섯 픽셀 중 가장 높은 값은 90입니다. 90의 50%는 45이므로 위 명령을 이 다섯 픽셀에 대해 수행해 봅니다. | 가장 높은 값인 255의 50%는 127.5입니다. |
* 60 > 45 --> 90 | * 160 > 127.5 --> 255 |
* 30 < 45 --> 0 | * 120 < 127.5 --> 0 |
* 48 > 45 --> 90 | * 48 < 127.5 --> 0 |
* 40 < 45 --> 0 | * 140 > 127.5 --> 255 |
* 90 > 45 --> 90 | * 230 > 127.5 --> 255 |
그러므로 결과는 | 그러므로 결과는 |
90, 0, 90, 0, 90 | 255, 0, 0, 255, 255 |
모든 픽셀 값이 90, 아니면 0으로 현격하게 갈립니다. 그러면 직접 convert를 그림 파일에 대해 직접 실행한 결과를 보도록 하지요. 대략 97% 정도를 threshold 값으로 주었을 때의 결과입니다. | 모든 픽셀 값이 255, 아니면 0으로 현격하게 갈립니다. 그러면 직접 convert를 그림 파일에 대해 직접 실행한 결과를 보도록 하지요. 대략 97% 정도를 threshold 값으로 주었을 때의 결과입니다. |
| |
{{ :project:detectsponsor:test01_mono.png?640 |}} | {{ :project:detectsponsor:test01_mono.png?640 |}} |
=== 첫번째 시도 방법 === | === 첫번째 시도 방법 === |
=== 구현 과정 === | === 구현 과정 === |
위 재료를 잘 버무리면 뭐 그런대로 괜찮은 결과가 나오리라 생각했습니다. 첫번째는 거의 쉘 스크립트에 가깝습니다만, 파이썬으로 만들도록 하지요. 쉘 스크립트를 만들면 윈도우 사용자들이 아마 불편하실거에요 ;-) | 위 재료를 잘 버무리면 뭐 그런대로 괜찮은 결과가 나오리라 생각했습니다. 첫번째는 거의 쉘 스크립트에 가깝습니다만, 파이썬으로 만들도록 하지요. 쉘 스크립트를 만들면 윈도우 사용자들이 아마 불편하실거에요 ;-) 대신 파이썬이라 할지라도 마치 쉘 스크립트와 유사하게 커맨드 라인을 실행하는 방식으로 1차 구현을 할 생각입니다. 라이브러리를 사용하는 게 아니라요. |
딱히 파이썬에서 라이브러리 정도를 만드는 것이 아닌, 명령어를 파이썬이 호출해서 쓰는 매우 심플한 형태로 만들어보았습니다. | |
| |
파이썬에서 외부 명령을 실행하는 가장 간단한 방법 중 하나는 os.system()을 이용하는 것입니다. 이것을 이용해 원본 동영상에서 일정 간격으로 한 프레임을 얻어내고, 그 한 프레임이 스폰서 영상인지 아닌지를 'convert' 프로그램과 'tasseract' 프로그램이 판단하는 것입니다. 정말 무식한 방법입니다만, 현재로서는 스마트한 방법 따위는 머릿속에 떠오르지 않네요. 그리고 정말 이 방법이 동영상에 대해서도 통하는지 의문이구요. | 파이썬에서 외부 명령을 실행하는 가장 간단한 방법 중 하나는 os.system()을 이용하는 것입니다. 이것을 이용해 원본 동영상에서 일정 간격으로 한 프레임을 얻어내고, 그 한 프레임이 스폰서 영상인지 아닌지를 'convert' 프로그램과 'tasseract' 프로그램이 판단하는 것입니다. 정말 무식한 방법입니다만, 현재로서는 스마트한 방법 따위는 머릿속에 떠오르지 않네요. 그리고 정말 이 방법이 동영상에 대해서도 통하는지 의문이구요. |
| |
=== 결과 분석 === | === 결과 분석 === |
tesseract라는 '문자 인식' 과정에 전적으로 의존합니다. threshold의 결과가 그다지 좋지 않았다면 tesseract의 인식률은 많이 떨어져버립니다. | tesseract라는 '문자 인식' 과정에 전적으로 의존합니다. convert -threshold의 결과가 그다지 좋지 않았다면 tesseract의 인식률은 많이 떨어져버립니다. |
일례로 아래와 같은 그림은 인식이 잘 됩니다. 95%로 threshold한 결과를 덧붙였습니다. | 일례로 아래와 같은 스폰서 영상은 비교적 인식이 잘 됩니다. 95%로 threshold한 결과를 덧붙였습니다. |
{{ :project:detectsponsor:shot0002.png?nolink&640 |}} | {{ :project:detectsponsor:shot0002.png?nolink&640 |}} |
{{ :project:detectsponsor:shot0002_mono.png?nolink&640 |}} | {{ :project:detectsponsor:shot0002_mono.png?nolink&640 |}} |
| |
일례로 다음과 같은 그림은 인식에 실패합니다. 마찬가지로 95%로 threshold한 결과를 덧붙였습니다. | 반면 아래와 같은 스폰서 영상은 인식에 실패합니다. 마찬가지로 95%로 threshold한 결과를 덧붙였습니다. |
{{ :project:detectsponsor:image_022.png?nolink&640 |}} | {{ :project:detectsponsor:image_022.png?nolink&640 |}} |
{{ :project:detectsponsor:image_022_mono.png?nolink&640 |}} | {{ :project:detectsponsor:image_022_mono.png?nolink&640 |}} |
| |
두 장의 이진화된 이미지 중 아래의 것은 인식에 처참하게 실패하는군요. 혹시 '제공' 부분만 잘라내서 인식하면 인식이 될까요? | 왜 이럴까요? 혹시 아래처럼 '제공' 부분만 잘라내서 인식하면 안될까요? |
{{ :project:detectsponsor:image_022_crop_mono.png?nolink |}} | {{ :project:detectsponsor:image_022_crop_mono.png?nolink |}} |
아닙니다. 인식이 잘 되지 않아요. 이것이 인식되게 하려면 threshold를 92%까지 낮춘 후 crop을 해야 인식 되더군요. | 의외로 잘 되지 않는군요. Threshold를 92%까지 낮춘 후 비슷하게 crop을 해 보았습니다. |
아래는 92% threshold와 crop의 결과입니다. | 아래는 그림은 92% threshold와 crop한 결과입니다. |
{{ :project:detectsponsor:image_022_92_mono.png?nolink&640 |}} | {{ :project:detectsponsor:image_022_92_mono.png?nolink&640 |}} |
{{ :project:detectsponsor:image_022_92_crop_mono.png?nolink |}} | {{ :project:detectsponsor:image_022_92_crop_mono.png?nolink |}} |
| |
저는 이렇게 결과를 분석했습니다. 인식이 잘 되는 이미지는 배경 이미지가 대부분 threshold를 넘지 않아 대개 자막으로 나오는 흰색 글자만이 이미지로 나옵니다. 그러나 배경 이미지가 상당히 밝으면 threshold값을 넘는 픽셀이 발생합니다. 이 경우 인식에 실패할 확률이 많이 높아집니다. threshold 또한 한자의 인식 결과에 꽤 예민하게 반응합니다. 그럴 수 밖에 없는 것이 한자는 획이 너무나 가늘고 복잡하게 많이 있습니다. 위의 그림 중 채도가 높아 실패한 경우를 보아도 그렇습니다. 제공이라는 글자를 따로 떼어내어 주변에 노이즈가 될 만한 상황을 제거했음에도 불구하고 95% threshold 값은 인식하지 못한 반면, 단 3%밖에 차이가 나지 않은 92% thrshold에서는 글자가 인식됩니다. | 이렇게 결과를 분석했습니다. 인식이 잘 되는 이미지는 배경 이미지가 대부분 threshold를 넘지 않습니다. 이렇게 되면 배경 이미지는 모두 검게 나오고 자막에 쓰인 흰색만 이미지로 나옵니다. tesseract는 이러한 이미지를 잘 인식해 글자로 만듭니다. |
| 그러나 배경 이미지가 비교적 밝은 이미지라면 threshold값을 넘는 픽셀이 많이 발생합니다. 이렇게 threshold가 넘는 값이 많아지면 tesseract의 문자 인식에 상당한 영향을 끼칩니다. |
{{ :project:detectsponsor:compare.png?nolink |}} | {{ :project:detectsponsor:compare.png?nolink |}} |
| |
| 한편 threshold 값 또한 한자의 인식 결과에 큰 영향을 주는 요소로 작용하는 것으로 보입니다. 일반적으로 한자는 영어에 비해 그 인식률이 낮은 것으로 알려져 있습니다. 글자 수도 워낙 많은 데다 모양이 복잡하기 때문이지요. '제공'이라는 글자 주변을 크롭해서 주변에 노이즈가 될 만한 상황을 제거했음에도 불구하고 95% threshold 크롭 버전은 tessesract가 인식하지 못했습니다. 반면 단 3%밖에 차이가 나지 않은 92% threshold 크롭 버전에서는 글자가 인식됩니다. 둘의 차이는 육안으로는 그렇게 도드라지게 보이지 않습니다. 자세히 들여다 보아야 95%쪽 글자 내부에는 듬성듬성 구멍이 많이 뚫려 있다는 것을 알아챌 수 있습니다. |
| === 다음을 위한 대책 === |
| ffmpeg, convert, tasseract, 이렇게 세 가지 커맨드라인 툳을 이용하다보니 각 단계에서 파일 입출력이 발생합니다. 그러다보니 프로그램의 실행속도가 많이 느려질 수 밖에 없겠지요. 이 부분만 해결해도 상당히 속도를 해결할 수 있으리라 생각합니다. |
| ffmpeg이 하던 동영상 읽기, convert가 하는 한 프레임의 threshold 처리는 opencv를 이용하고, tesseract 또한 커맨드 라인이 아닌, 라이브러리가 제공하는 API를 이용한다면 어떨까요? 이것만으로도 속도는 많이 개선될 수 있을 것 같습니다. |
| 물론 '파이썬'이라는 언어 자체가 가진 느림이 있습니다만, 그건 그냥 느림의 미학 LOL 으로 남겨두겠습니다. 아직은 "파이썬이 느려서 프로그램이 느린 거야!"라고 주장할 단계가 아닌 듯합니다. |
| |
| 또한 제공이라는 글자는 거의 화면의 12시 방향에 고정되어 나오므로 tasseract가 입력 영상의 모두를 처리해서 인지할 필요 없이, 거의 '제공'이라는 단어가 나오는 부분만 잘라내어 입력을 할 수 있을 것입니다. 그렇게 하면 tessertact가 인식하는 속도도 비약적으로 향상되겠지요. |
| 한편 이런 생각을 해 볼 수도 있습니다. 애초에 "제공"이라는 글자 자체를 인식해서 텍스트로 결과를 정확히 얻어 내야만 되는 것일까? 하는 문제이죠. 사실 사람도 그렇습니다. 저것이 스폰서 화면이다, 아니다를 판별할 때 한 글자 한 글자를 꼼꼼하게 읽어서 한 글자도 틀리지 않게 인식한 다음 판단하나요? 그렇진 않지요. 대충 어떤 화면에 흰색 글자가 고정되어 나타나고, '고노 방구미와~ 고란노 스폰사데~' 같은 음성이 나오며, 흰색 글자는 **평소에 보아 오던 대로** 대략 제공이나 스폰서의 로고들이 나온다는 사실만 슥 보고 바는 겁니다. 예컨데 누가 일부러 'KADOKAWA'라는 글자를 'KADOKAVVA'라고 글자를 적당히 틀리게 썼다고 생각해 보지요. 물론 그걸 정확히 캐치해내는 시청자도 있겠지만, 대개 많은 이는 그걸 무시하거나 인지하지 못한 채 넘어갈 겁니다. 사악하게(?) VV의 자간을 더욱 그럴듯하게 조절하면 모두를 깜빡 속일 수도 있지만, 오히려 그 경우라면 KADOKAWA든 KAOKA**VV**A든 어쨌든 사람들은 평소 접하던 오리지널인 KADOKAWA라고 생각할테니 홍보 효과에는 별 차이가 없을 거란 말입니다. |
| |
| 영상이 아닌 '음성까지 동원하여 스폰서 화면을 캐치해보면?'이란 아이디어는 생각해 본 적이 있었으나 제가 음성 인식 쪽에는 영상 처리보다도 아는 것이 없는데다, .... 스폰서 영상 하나 탐지하자고 별 난리를 치는 꼴이 되는 것 같네요. 그냥 영상 처리를 이용해 인식하는 것으로 만족하겠습니다. |
| 그리고 위 문단에서 '**평소 보아오던 대로**'라는 부분은 특별히 강조한 이유가 있습니다. 저것을 활용하면 굳이 tesseract라는 문자 인식 기능을 붙이지 않아도 될 것 같은 생각이 드는데요, 아직은 그 쪽으로는 생각하지 않고, 일단 tesseract가 깔끔하게 문자를 인식해 낼 수 있도록 처리하는 쪽으로 방향을 잡았으면 합니다. |
| |
| ===== 결론 ===== |
| 갑자기 결론이 뜬금없이 나와 이상하긴 합니다만, 저는 '이러이러하게 하면 성능은 개선될 거야'라고 제안하는 수준에서 이 문서와 작업을 마치고 싶습니다. |
| 사실 문서의 내용이야 간단하게 파이썬, 프로그래밍에 관심 있으신 분들이 한 번 참고할 만한 내용이라 생각하므로 공개해서 서로 나눔을 해도 크게 문제가 없다고 생각하지만, 그래도 이 문서를 계속 발전시켜야 할 지에 대해서는 좀 의문이 들기 때문입니다. |
| |
| 여기까진, 정말 여기까지는, 호기심의 일환으로 진행해 보았습니다. 그러나 아무리 제가 문서에서 공유를 조장하려는 의도가 아니라고 못을 박긴 했어도, 이유야 어쨌든 음성적인 콘텐츠를 대상으로 작업을 한 것이 사실입니다. 이러한 사실을 눈감은 채 그렇게까지 공을 들여 작업하고 싶은 생각은 없습니다. 우연히 들게 된 개인적인 호기심을 충족시키는 면에서는 이 정도로도 충분히 성공적이라고 생각하니까, 이 정도로 마무리짓는 것이 옳지 않을까 합니다. 만일 합법적인 콘텐츠 분야에서 문서가 서술한 어떠한 부분이 필요하다는 요구가 있다면야 저는 주저없이 이 문서 작업을 계속할 의도가 있습니다. 그러나 그렇지 않는 한은 잘 모르겠습니다. |
| |
| /* |
==== 두번째 시도 ===== | ==== 두번째 시도 ===== |
===두번째 시도 방법 === | ===두번째 시도 방법 === |
=== 구현 과정 === | === 구현 과정 === |
=== 구현 결과 === | === 구현 결과 === |
| |
===== 결론 ===== | ===== 결론 ===== |
/* 스폰서 영상이란 것 자체가 일본방송을 립해서 올리는 그 영상에만 해당하는 카테고리라서 | 스폰서 영상이란 것 자체가 일본방송을 립해서 올리는 그 영상에만 해당하는 카테고리라서 |
불법공유를 양성화하자는 것도 아니고, 단지 개인적인 호기심이었으니 여기까지 한 것으로 만족한다. | 불법공유를 양성화하자는 것도 아니고, 단지 개인적인 호기심이었으니 여기까지 한 것으로 만족한다. |
만일 합법적인 분야에서 이러한 방법이 유용하고 가치 있는 일이라면 주저않고 성능을 개선할 의도가 있다. */ | 만일 합법적인 분야에서 이러한 방법이 유용하고 가치 있는 일이라면 주저않고 성능을 개선할 의도가 있다. |
| |
/* 프로그램을 더 개선할 방향: 더 빠른 언어로 구현/휴리스틱 활용/스폰서 글자가 나오는 위치의 조정 */ | 프로그램을 더 개선할 방향: 더 빠른 언어로 구현/휴리스틱 활용/스폰서 글자가 나오는 위치의 조정 */ |