precision, recall의 이해

영상처리 2017.01.02 16:21

자신이 어떤 기술을 개발하였다. 예를 들어 이미지에서 사람을 자동으로 찾아주는 영상 인식 기술이라고 하자. 이 때, 사람들에게 "이 기술의 검출율은 99.99%입니다"라고 말하면 사람들은 "오우...!!!" 하면서 감탄할 것이다. 반면에 "이 기술의 검출율은 50%입니다"라고 말하면 사람들은 별 관심을 보이지 않거나 "그것도 기술이라고..." 생각할 것이다.


이것은 전형적인 일반인의 반응이다. 이러한 반응이 크게 잘못된 것은 아니지만 이러한 반응에는 명시되지 않은 한 가지 전제가 깔려있다. 그것은 '이 기술은 절대로 오검출을 하지 않는다' 이다.


문제를 조금 바꿔보자. A와 B라는 기술이 있다. A라는 기술은 이미지에 있는 사람을 99.99% 잡아내지만 이미지 1장 당 평균 10건 정도의 오검출이 발생한다. 즉, 사람이 아닌 부분도 사람이라도 검출하는 경우가 빈번히 발생한다. 반면에 B라는 기술은 이미지에 있는 사람들 중 50%밖에 못 잡아내지만 오검출은 거의 발생하지 않는다. 그렇다면 A라는 기술과 B라는 기술 중 어느 기술이 뛰어난 기술인가? 그것은 응용에 따라 달라질 수 있지만 중요한 것은 검출율 만으로 기술을 평가하는 것은 적합하지 않다는 것이다.


☞ 검출율 100%의 물체인식 기술은 누구라도 손쉽게 만들 수 있다. 그것은 모든 입력에 대해 항상 물체가 검출된 것으로 반환하도록 알고리즘을 구현하면 되기 때문이다.


인식/탐지 기술의 성능을 평가하기 위해서는 검출율과 정확도를 동시에 고려해야 한다. 검출율은 직관적으로는 detection rate이지만 학문적으로는 recall이란 용어를 사용한다. 그리고 정확도에는 precision이란 용어를 사용한다. recall은 대상 물체들을 빠뜨리지 않고 얼마나 잘 잡아내는지를 나타내고 precision은 검출된 결과가 얼마나 정확한지 즉, 검출 결과들 중 실제 물체가 얼마나 포함되어 있는지를 나타낸다. 


그렇게 어려운 개념이 아님에도 불구하고 의외로 precision과 recall의 개념을 정확히 이해하지 못하고 혼동스러워하는 경우가 종종 있다. 그 이유는 detect라는 말에 대해서 혼동을 가지는 경우가 많기 때문이다. detect라는 단어는 단지 알고리즘이 무언가를 검출했다는 것을 의미할 뿐이다. 우리가 개발한 알고리즘은 완벽하지 않기 때문에 알고리즘이 검출한 결과에는 실제 물체를 물체라고 검출한 것도 있지만 물체가 아닌 것을 물체라고 검출한 수도 있다. 하지만 사람들은 흔히 detect라는 말을 실제 물체를 검출한 경우로만 한정하여 생각하기 쉽다. 이 경우 precision, recall의 개념을 정확하게 이해하지 못하고 혼동스러워하는 원인이 된다.


어떤 인식 알고리즘의 precision과 recall을 정의해 보면 다음과 같다. detection이란 말이 단지 알고리즘의 출력(결과)임을 상기하면 두 용어의 개념이 보다 명확해진다.




인식 알고리즘의 성능과 관련해서 마지막 오해는 어느 한 고정된 값으로 알고리즘의 성능을 평가하는 것이다. 예를 들어, '어느 알고리즘의 성능은 검출율(recall) 0.9, 정확도(precision) 0.7이다'라고 표현하는 식이다. 하지만 알고리즘의 성능을 어느 한 값으로만 표현하고 평가하는 것은 올바른 방법이 아니다. 왜냐하면 알고리즘의 recall과 precision은 알고리즘의 파라미터 조절에 따라 유동적으로 변하는 값이기 때문에 어느 한 값으로는 알고리즘 전체의 성능을 제대로 표현할 수 없기 때문이다.


☞ 일반적으로 알고리즘의 검출율(recall)과 정확도(precision)는 서로 반비례 관계를 가진다. 알고리즘의 파라미터를 조절해 검출율을 높이면 오검출(false alarms)이 증가하고 반대로 오검출을 줄이기 위해 조건을 강화하면 검출율(recall)이 떨어진다.


따라서 인식 알고리즘들의 성능을 제대로 비교하고 평가하기 위해서는 precision과 recall의 성능변화 전체를 살펴봐야 한다. 그리고 그러한 대표적인 방법은 precision-recall 그래프를 이용하는 것이다.


Precision-recall 그래프

알고리즘의 파라미터(threshold 등) 조절에 따른 precision과 recall의 값의 변화를 그래프로 표현한 것. 일례로 아래 그림은 'Object Detection with Discriminatively Trained Part Based Models', TPAMI 2010 논문에서 DPM 모델의 여러 변형에 따른 성능변화를 그래프로 표현한 것이다.

그림 1. precision-recall 그래프의 예


precision-recall 그래프는 다양한 형태로 변형되어 표현될 수 있는데 recall 대신에 miss rate (miss rate = 1 - recall), precision 대신에는 false alarm rate (false alarm rate = 1 - precision) 등이 사용될 수 있다.


Average Precision (AP)

precision-recall 그래프는 어떤 알고리즘의 성능을 전반적으로 파악하기에는 좋으나 서로 다른 두 알고리즘의 성능을 정량적으로(quantitatively) 비교하기에는 불편한 점이 있다. 그래서 나온 개념이 average precision이다. Average precision은 인식 알고리즘의 성능을 하나의 값으로 표현한 것으로서 precision-recall 그래프에서 그래프 선 아래쪽의 면적으로 계산된다 (그림 2). 위 그림 1의 예에서 괄호 안의 숫자가 해당 알고리즘의 average precision 값이다. 그리고 average precision이 높으면 높을수록 그 알고리즘의 성능이 전체적으로 우수하다는 의미이다. 컴퓨터 비전 분야에서 물체인식 알고리즘의 성능은 대부분 average precision으로 평가한다.


그림 2. average precision


F-measure

알고리즘의 precision-recall 성능을 하나로 숫자로 표현하는 또 다른 방법이다. F-measure는 precision과 recall의 조화평균으로 계산된다.




※ 참고사항: Precision과 Accuracy


혼동의 여지가 있어서 의도적으로 언급하지 않은 내용이 있는데 그것은 accuracy와 precision의 구분이다 (원래는 언급하지 않으려고 했는데.. 아래 댓글에 답변을 달다보니 필요해서 추가한 내용입니다). 먼저, 유의해야 할 사항이 하나 있는데 그것은 동일한 단어라 할지라도 그것이 사용된 context에 따라서 의미가 달라질 수 있다는 점이다.


먼저, 단어 자체의 의미로 보면 accuracy는 정확도, precision은 정밀도로 번역되며 어떤 시스템(system)의 특징 또는 성능을 평가하는 척도로서 사용된다. 이 때, accuracy는 시스템의 결과(출력)가 참값(true)에 얼마나 가까운지를 나타나고 precision은 시스템이 얼마나 일관된 값을 출력하는지를 나타낸다. 즉, accuracy는 시스템의 bias를, precision은 반복 정밀도를 나타낸다. 예를 들어, 몸무게를 재는 저울이 있는데 50kg인 사람을 여러 번 측정했을 때 60, 60.12, 59.99, ... 와 같이 60 근방의 값으로 측정했다면 이 저울의 accuracy는 매우 낮지만(에러가 10kg이나 발생함) precision은 매우 높다고 말할 수 있다.


다음으로, 기계학습의 이진 분류(binary classification) 문제에 있어서는 precision이 조금 다른 의미로 사용된다(accuracy는 유사한 의미). Accuracy는 시스템이 올바르게(true를 true로 판단하고 false를 false로 판단) 판단하는 정도를 나타내며 Accuracy = (올바른 판단 횟수) / (판단 총 횟수) = (TP + TN) / (TP + TN + FP + FN)로 계산된다. 반면, precision은  시스템이 true로 판단한 경우에 한해서의 정확도로서 precision = (실제 true 횟수) / (true로 판단한 횟수) = TP / (TP + FP)로 계산된다. 그리고 컴퓨터 비전 분야에서 사용하는 precision은 이 두번째 의미로서의 precision이다. 즉, 검출 시스템이 검출한(true라고 판단한) 결과에 대해서만 정확도를 측정한 것이 precision이다.


컴퓨터 비전 분야의 검출 시스템(detection system)에서는 accuracy는 거의 사용하지 않고 precision만을 사용하기 때문에 precision을 '정확도'라고 번역해도 accuracy와 혼동의 여지가 적다. 그리고 precision의 의미가 반복 정밀도(repeatability)가 아니기 때문에 이 글에서는 의미상 '정밀도'라고 번역하지 않고 '정확도'라고 표현하였다.(삭제 이유는 아래 내용 참조)


☞ (추가내용2) 나중에 다시 곰곰히 생각해 보니 이진 classification 문제나 비전에서 사용하는 precision도 '반복 정밀도'의 의미로도 해석이 가능함을 깨닫게 되었습니다. 즉, 실제 true인 것들에 대해 시스템을 테스트했을 때 그 답변이 항상 일정하면 precision이 높은 것이고 들쭉 날쭉하면 즉, 어느 때는 true라고 답변했다가 다른 때는 false라고 답변했다가 하면 precision이 낮은 것이라고 해석하면 그 뜻이 잘 일치됩니다. 그런 관점에서 보면 precision을 원래 단어 뜻 그대로 '정밀도'로 번역하는 것이 보다 정확할지도 모르겠습니다.. 하지만, 글을 다시 고치기는 귀찮고 또 '정확도'라고 표현하는 것이 직관적으로 이해하기 쉬운 면이 있어서 그냥 그대로 두렵니다.. @@;;


☞ 그리고 recall도 정확히 번역하면 '재현율'이라고 하는 게 맞고, 또 기술적(학문적) 용어로도 재현율이 맞겠습니다. 하지만 일반인의 용어로서 그리고 보다 직관적이다고 생각되어 '검출율'이라고 표현했습니다.


by 다크 프로그래머

저작자 표시 비영리 변경 금지
신고
  • BlogIcon 합격통지서 2017.01.04 16:43 신고 ADDR 수정/삭제 답글

    좋은글 감사합니다.

  • 팔공선녀님 2017.01.05 14:34 신고 ADDR 수정/삭제 답글

    새해 복 많이 받으세요~ 감사합니다

  • hojak99 2017.01.09 20:12 신고 ADDR 수정/삭제 답글

    감사합니다. 많이 배워가네요

  • 나이스데이 2017.01.23 11:12 신고 ADDR 수정/삭제 답글

    좋은 글 감사합니다.

  • 도둑성 2017.01.24 16:15 신고 ADDR 수정/삭제 답글

    안녕하세요 다크프로그래머님
    눈팅으로만 보다가 질문 댓글 남깁니다!
    Superpixel 결과 비교시에 자주 사용되는 Boundary Recall이 존재하는데

    이것에 대해 아시는게 있는지요... 비교로는 많이 사용되지만 소스라던가.. 정보가 너무 부족하더라고요...

    • BlogIcon 다크pgmr 2017.01.24 18:16 신고 수정/삭제

      저도 찾아보니 http://davidstutz.de/superpixel-algorithms-overview-comparison/에 잘 설명되어 있는 것 같습니다. 한번 살펴보시고 잘 파악이 안되는 부분이 있으면 댓글 남겨주시기 바랍니다.

    • 도둑성 2017.01.25 12:45 신고 수정/삭제

      감사합니다 덕분에 많이 배웁니다.

  • 공부중 2017.01.25 08:21 신고 ADDR 수정/삭제 답글

    학부생인데 정말 많이 알아갑니다 ㅠㅠ 감사합니다

  • 스냑 2017.01.25 17:51 신고 ADDR 수정/삭제 답글

    그럼 정확도라는 말은 미검지한 항목을 제외하고 측정되는건가요? 앞으로는 이부분 꼼꼼히 체크해서 데이터를 분석해야겠네요 ㅎㅎ

    • BlogIcon 다크pgmr 2017.01.25 22:34 신고 수정/삭제

      네, precision은 미검지한 부분은 고려치 않고 검지한 부분에 대해서만 정확도를 측정한 것입니다. (사실.. 쓸데없이 문제를 복잡하게 만드는 측면이 있어서 언급하지 않은 부분이 한 가지 있는데 그건 accuracy입니다. 댓글로 달기에는 글이 길어져서 본문에 관련 내용을 추가하였으니 참고하시기 바랍니다)

  • 농구공 2017.02.15 22:49 신고 ADDR 수정/삭제 답글

    음... precision은 정밀도로 번역하는게 맞는데, recall을 검출률이라고 번역하는 곳이 있나요? 보통 재현율이라고 하지않나요. 특히, 본문서도 지적한거 같은데, recall을 검출률이라 번역하면 detection rate(probability of detection)하고 듣는 한국인들은 헷갈려서 위험할거 같은데요.

    • BlogIcon 다크pgmr 2017.02.16 07:49 신고 수정/삭제

      네.. 그렇겠네요. 한편으로 검출율이라고 하면 시스템이 무언가 출력을 내는 율과 혼동할 수 있겠습니다..
      영상에서 사람을 검출하는 시스템이 있는데 이 시스템의 재현율과 정밀도, 이 시스템의 검출율과 정확도... 농구공님은 어떤 게 더 잘 들어오나요? 기술적 용어로는 재현율, 정밀도가 맞고 개념의 혼동의 여지가 적은 것 같습니다. 하지만 일반인의 언어로서 검출율과 정확도가 개인적으로는 더 마음에 와 닿습니다. 그래도 학문을 하는 사람 입장에서는 재현율과 정밀도라고 표현하는게 맞겠죠?? 오락 가락 합니다..

  • 농구공 2017.02.16 12:43 신고 ADDR 수정/삭제 답글

    공학에서 사용되는 용어니까 일반인들에게 설명이 필요한건 어쩔수 없는거죠. 암튼 리콜 프리시전은 각각 재현율 정밀도로 해석하는게 정의상 맞습니다. 일단 프리시전 정의부터 다시보면 tp/(tp+fp) 인데 시스템 출력의 정밀성을 얘기하는거잖아요. 전체 시스템의 true response(tp&fp)들 중에 tp를 얘기하는거니까요. 글고 재현율은 tp/(tp+fn)이고 즉 데이터셋에서 true인 샘플들(tp&fn)중 시스템의 tp이니까 임의의 데이터셋에서 시스템이 tp를 발생할 확률을 말하는거죠. 왜냐면 여러 데이터셋에서 리콜을 측정한 값의 평균은 임의의 데이터셋에서 그정도의 tp를 재현해 낸다라는 의미를 가지니까요.

  • 이순빈 2017.02.28 16:43 신고 ADDR 수정/삭제 답글

    데이터 과학 책에서 흔히 설명하는 혼동 행렬(Confusion Matrix) 개념이네요. 실제 상황에서는 정확도가 같은 모델이어도 음성이 나타날 경우가 지극히 적고, 그 1번을 놓치게 되면 큰 손해를 불러일으킬 경우에 따라 확률에 기댓값 등의 가중치를 부여하며 평가하는 방식도 있었던 것 같습니다.

    OpenCV를 처음 공부할 때부터 다크프로그래머님 블로그 잘 보고 있습니다. Convolutional Neural Network와 같은 딥 러닝 분야에 대해서는 어떠신지 궁금합니다.
    기계학습 전반이나, NIPS 논문 리뷰 포스팅을 올리신 걸 보면 내공이 상당하실 것 같은데요. 최근 동향은 이미지에서 고차원적인 정보를 뽑아내는 것은 물론 Generative Model이라 하여

    Style과 Content라는 고차원적 정보를 수준높게 분리해내는 Style Transfer, 판별자(Discriminator)를 두어 진짜에 가까운 가짜 이미지를 생성하는 DCGAN, 외곽선 등의 적은 정보만으로 내용이미지를 추론하는 pix2pix, 인접 픽셀(정보)의 분포를 추론하는 PixelCNN 같은 이미지 생성 기법에 있어서 흥미롭고 엄청난 결과들을 보여주고 있습니다. 가능하다면 이러한 내용들도 다크프로그래머님 블로그에서도 볼 수 있었으면 좋겠습니다.

    • BlogIcon 다크pgmr 2017.02.28 18:43 신고 수정/삭제

      dnn이 나온 이후로 기술의 흐름이 너무 빨라져서 그동안 쌓아온 것들이 한순간에 과거의 것들이 되어버리고 엄청난 변화를 따라가지 못하는 사람들을 순간 바보로 만듭니다. 저도 그러한 바보 중 한명이고 dnn으로 인해 가능해지고 있는 수많은 응용과 변화들에 감탄을 하고 있습니다. ^^

  • 북극곰괴력 2017.04.03 16:11 신고 ADDR 수정/삭제 답글

    안녕하세요 다크님. 좋은 글들 잘 읽어보았습니다.
    한가지 여쭤볼게 있어서그러는데, 차량 검출을 하는 프로그램을 만드는 중인데 검출률(recall)을 구할 때 만약 첫 프레임에서 10대의 차량 중 9대가 검출되어 검출률 90%, 두 번째 프레임에서 5대의 차량 중 4대가 검출되어 검출률 80%라고 치면 검출률은 각 프레임들의 평균인 85%가 되는것인지요?

    이렇게 구하는 것이 맞다면, 만약 첫 번째 프레임에 10대의 차량중 9대가 검출되고 두 번째 프레임에 1대중 0대가 검출되었다고 치면 총 11대의 차량중 9대를 찾았지만 검출률은 50%정도인 것인가요?

    • BlogIcon 다크pgmr 2017.04.03 20:34 신고 수정/삭제

      안녕하세요. 보통 검출율, 오검출율 등은 프레임 구분을 하지 않고 총 개수를 가지고 산출을 합니다. 즉, 첫 프레임에서 10대의 차량 중 9대가 검출되고 두 번째 프레임에서 5대의 차량 중 4대가 검출되었다면 총 15대의 차량 중 13대가 검출된 것이므로 검출율은 13/15가 됩니다.

말말말

잡기장 2016.11.29 15:29

훌륭한 지도자는 역사를 바꾸고, 저열한 권력자는 역사책을 바꾼다

전우용 (역사학자), 2015.10.09


내 아이디어, 상상력, 창의력은 듣기와 읽기로 생기는게 아니다. 말하기와 쓰기로 생긴다. 자기의 생각을 말하고 자기 생각을 쓸 때 상상력이 생기고 창의력이 생긴다. 말해보고 써야 내가 누군지 안다. 블로그도 좋고 메모장도 좋다. 말하기와 쓰기로 자신을 스스로 풀어낸 사람은 남에게 업신여김을 당해도 불행해하지 않는다.

강원국 (전 대통령 연설 비서관), 말하는대로 2016.11.23


선택은 포기다. 우리가 어느 하나를 선택한다는 것은 결국 그외 많은 것들을 포기해야만 하는 일이다. 그 어느것도 포기하지 못하는 것은 결국 아무것도 선택하지 않는 것과 같다.

허태균 (심리학 교수), 대한민국에서 행복찾기 2015.12.19


우리가 역사를 배우는 이유는 뭔가요? 그건, 내가 어떻게 살아왔고 어떤 일을 겪어 왔는지 나의 역사를 빼놓고는 너희들이 나를 제대로 알 수 없는 것처럼, 한 사회나 나라를 제대로 이해하려면 꼭 알아야 하는 게 바로 그 사회나 나라의 역사거든. 우리나라 역사를 잘 알면 우리가 어떤 사람들인지, 우리가 지금 왜 이렇게 살고 있는지 금세 이해가 되지. 현재를 제대로 이해하면 그 미래도 올바른 방향으로 잘 꾸려 나갈 수 있지 않겠니? 그뿐만이 아니야. 역사를 공부하면 다른 나라들에 대한 이해도 깊어지게 되지. 미국의 역사를 알면 미국 사람들의 말과 행동이 이해가 되고, 아프리카의 역사를 알면 아프리카 사람들의 생활 모습이 이해가 되지. 그러면서 서로 다른 사회의 역사와 문화를 존중할 수 있게 되고.

용선생의 시끌벅적 한국사


급한 일에 시간을 쏟지 말고 중요한 일에 시간을 쏟아라 (중요한 일: 자신의 목적을 달성하는데 도움이 되는 일, 급한 일: 주로 다른 이의 목적을 달성하는데 관련된 일)

Eisenhower (미 34대 대통령)



저작자 표시 비영리 변경 금지
신고

'잡기장' 카테고리의 다른 글

말말말  (0) 2016.11.29
한국의 영어 교육  (0) 2016.11.23
꽃 한송이  (19) 2016.08.29
Stop Trying to Create a Killer Resume  (18) 2015.06.24

OpenCV + Extra Module을 하나의 world 파일로 build하기

프로그래밍/opencv 2016.11.23 19:19

opencv 3.0 버전 이상부터는 highgui, imgproc, ... 등등 opencv에 있는 여러 모듈들을 하나의 world 파일로 build할 수 있는 기능이 제공된다.

  • 3.0 버전: opencv_world300.lib, opencv_world300.dll
  • 3.1 버전: opencv_world310.lib, opencv_world310.dll

하지만 opencv 기본 모듈에 포함되지 않은 extra module들을 같이 포함하여 build할 경우에는 각 모듈마다 별도의 dll 파일들이 생성되어 이것들을 모두 들고 다녀야 하는 번거로움이 있다.


opencv 기본모듈과 extra 모듈을 모두 포함하여 하나의 world 파일로 build 하는 방법이 있는지 인터넷을 찾아봤지만 아무리 뒤져도 관련 방법을 찾을 수 없었다. 그래서 스스로 이것 저것 해보다가 해결책을 찾게 되었는데 조금 번거롭긴 하지만 아래와 같이 하면 single build가 가능하다.



Step 1. 준비물


opencv와 extra module의 소스코드는 master branch의 최신 버전을 git clone이나 zip파일로 직접 다운로드한다. 선호에 따라서 정식 release 버전을 받을수도 있겠지만 여기서는 최신 버전을 git에서 직접 다운받는 것을 가정한다.



Step 2. extra module을 opencv module과 합치기


opencv 설치 폴더를 opencv, extra module 설치 폴더를 opencv_contrib라고 했을 때, opencv_contrib\module\에 있는 extra 모듈들을 전부 opencv\module\ 밑으로 옮긴다 (처음 다운받은 폴더에 보면 opencv\modules\에는 core, highgui, imgproc 등의 기본적인 모듈들이 존재하고, opencv_contrib\modules\에는 aruco, bgsegm, tracking, optflow 등의 extra module들이 존재한다. 이 extra module들 전체를 그대로 opencv\modules\ 밑으로 복사 또는 이동시켜서 기본 모듈들과 합친다).



Step 3. cmake 설정하기


cmake를 실행시킨 후 opencv 설치 폴더를 source로 설정하고, binary를 build할 폴더를 새로 생성하여 지정한 후 configure 버튼을 누르면 extra module들이 기본 모듈들과 함께 활성화되어 선택할 수 있게 됨을 확인할 수 있다.


이제 cmake에서 자신의 필요에 맞게 build 옵션들을 적절히 설정한다. 이 때, 기본적으로 설정해야 할 부분은 다음과 같다.


<CMakeCache.txt>

BUILD_opencv_world:BOOL=ON

BUILD_opencv_contrib_world:BOOL=OFF

OPENCV_ENABLE_NONFREE:BOOL=ON

OPENCV_EXTRA_MODULES_PATH:PATH=

BUILD_SHARED_LIBS:BOOL=ON

BUILD_WITH_STATIC_CRT:BOOL=OFF


opencv_world는 지금 하고 있는 일의 가장 중요한 목적이므로 당연히 체크하고 opencv_contrib_world는 체크해제, OPENCV_ENABLE_NONFREE는 활성화, OPENCV_EXTRA_MODULES_PATH는 기본값인 공백으로 그대로 놔둔다. dll 빌드를 위해서는 위와 같이 BUILD_SHARED_LIBS를 체크하고 만일 static library로 빌드할 경우에는 이 항목을 체크 해제한다 (static library로 빌드할 경우에도 이후의 절차를 따르면 하나의 world 파일로 빌드된다).


기타 다른 옵션들은 자신의 필요에 따라 적절하게 설정한다. 하지만 빠른 빌드를 위해서 아래와 같이 부가적인 요소들은 제거해도 좋다 (당연한 말이겠지만 build opencv apps와 같이 자신에게 필요한 기능이 있을 경우에는 자신이 원하는대로 설정한다).


BUILD_DOCS:BOOL=OFF

BUILD_EXAMPLES:BOOL=OFF

BUILD_PACKAGE:BOOL=OFF

BUILD_PERF_TESTS:BOOL=OFF

BUILD_TESTS:BOOL=OFF

BUILD_opencv_apps:BOOL=OFF


이제 설정을 마친 후 configure 버튼을 다시 누르면 "Error in configuration process, project files may be invalid"라는 팝업과 함께 다음과 같은 에러 메시지들이 출력된다.


CMake Error at cmake/OpenCVModule.cmake:390 (message):
WARNINGUnresolved dependencies or loop in dependency graph (3)

Processed OPENCV_MODULE_opencv_dnn_DEPS:
opencv_aruco;opencv_bgsegm;opencv_bioinspired;opencv_calib3d;opencv_ccalib;opencv_core;opencv_datasets;opencv_dpm;opencv_face;opencv_features2d;opencv_flann;opencv_fuzzy;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_line_descriptor;opencv_ml;opencv_objdetect;opencv_optflow;opencv_phase_unwrapping;opencv_photo;opencv_plot;opencv_reg;opencv_rgbd;opencv_shape;opencv_stereo;opencv_stitching;opencv_structured_light;opencv_superres;opencv_surface_matching;opencv_text;opencv_tracking;opencv_video;opencv_videoio;opencv_videostab;opencv_world;opencv_xfeatures2d;opencv_ximgproc;opencv_xobjdetect;opencv_xphoto


Good modules:
opencv_core;opencv_flann;opencv_imgproc;opencv_ml;opencv_photo;opencv_reg;opencv_surface_matching;opencv_video;opencv_fuzzy;opencv_imgcodecs;opencv_shape;opencv_videoio;opencv_highgui;opencv_objdetect;opencv_plot;opencv_superres;opencv_xobjdetect;opencv_xphoto;opencv_bgsegm;opencv_bioinspired;opencv_dpm;opencv_face;opencv_features2d;opencv_line_descriptor;opencv_text;opencv_calib3d;opencv_ccalib;opencv_datasets;opencv_rgbd;opencv_stereo;opencv_stitching;opencv_tracking;opencv_videostab;opencv_xfeatures2d;opencv_aruco;opencv_phase_unwrapping;opencv_structured_light


Bad modules: opencv_optflow;opencv_world;opencv_ximgproc
Call Stack (most recent call first):
cmake/OpenCVModule.cmake:509 (__ocv_sort_modules_by_deps)
cmake/OpenCVModule.cmake:302 (__ocv_resolve_dependencies)
modules/CMakeLists.txt:7 (ocv_glob_modules)


에러 메시지를 잘 보면 dnn, optflow, ximgproc에서 문제가 발생했다는 것을 알수 있다. 이 문제는 ximgproc 모듈이 world 프로젝트에 포함되지 않아서 발생한 문제이다. opencv\modules\ximgproc\CMakeLists.txt 파일을 열어서 아래와 같이 수정한다 (set(OPENCV_MODULE_IS_PART_OF_WORLD OFF)를 #으로 주석처리하고 target_link ... 도 주석처리).


set(the_description "Extended image processing module. It includes edge-aware filters and etc.")

#set(OPENCV_MODULE_IS_PART_OF_WORLD OFF)

ocv_define_module(ximgproc opencv_imgproc opencv_core opencv_highgui opencv_calib3d WRAP python)

#target_link_libraries(opencv_ximgproc)


이후 configure를 해 보면 ximgproc에 대해 dependency를 가지고 있던 dnn 모듈과 optflow 모듈의 에러가 사라짐을 확인할 수 있다. 그런데, 이번에는 xobjdetec에서 다음과 같은 새로운 에러 메시지가 발생한다.


CMake Error at modules/xobjdetect/CMakeLists.txt:4 (add_subdirectory):

  add_subdirectory given source "tools" which is not an existing directory.

Call Stack (most recent call first):

  modules/world/CMakeLists.txt:13 (include)

  modules/world/CMakeLists.txt:26 (include_one_module)


이 에러는 opencv\modules\xobjdetect\tools라는 폴더를 world 프로젝트에서 인식할 수 없기 때문에 발생한 문제이다. 간단하게, opencv\module\xobjectdetect\tools 폴더 전체를 opencv\modules\world\tools로 복사한 후 다시 configure 버튼을 누르면 관련 에러가 사라진다.


그런데, 다운받은 opencv 버전에 따라서 이 외에도 유사한 에러들이 다양하게 발생할 수 있는데 다운받은 버전에서는 아래와 같이 xfeatures2d 에서도 에러가 발생하였다.


CMake Error at modules/xfeatures2d/CMakeLists.txt:4 (include):

include could not find load file:

cmake/download_vgg.cmake
Call Stack (most recent call first):
modules/world/CMakeLists.txt:13 (include)
modules/world/CMakeLists.txt:26 (include_one_module)

CMake Error at modules/xfeatures2d/CMakeLists.txt:5 (include):
include could not find load file:

cmake/download_boostdesc.cmake
Call Stack (most recent call first):
modules/world/CMakeLists.txt:13 (include)
modules/world/CMakeLists.txt:26 (include_one_module)


이 에러도 앞서와 마찬가지로 opencv\modules\xfeatures2d\cmake 폴더 전체를 opencv\modules\world\cmake로 통째로 복사하면 해결된다 (opencv 버전에 따라서 이 외에도 다양한 에러들이 발생할 수 있는데 유사한 방식으로 하면 모두 해결 가능하다).


이상과 같이 하면 일단 configure까지는 성공적으로 완료된다. 이제 cmake의 generate 버튼을 눌러서 visual c++ 프로젝트를 생성한 후 컴파일만 하면 된다. 그런데, build할 폴더에 생성된 OpenCV.sln 파일을 열어보면 opencv_dnn, opencv_saliency, opencv_ts, opencv_world 이렇게 4개의 모듈이 생성되어 있음을 확인할 수 있다 (다운받은 opencv 버전에 따라서 조금씩 차이가 있을 수 있다). 이 말은 dnn, saliency, ts는 world에 포함되지 않고 별도 모듈로 컴파일된다는 의미이다. 따라서, 이 문제를 해결하기 위해서는 cmake의 generate 버튼을 누르기 전에 opencv\modules\saliency\CMakeList.txt 파일을 아래와 같이 수정한다. 즉, saliency 모듈이 world의 일부가 되도록 설정을 수정한다.


set(the_description "Saliency API")

#set(OPENCV_MODULE_IS_PART_OF_WORLD OFF)

ocv_define_module(saliency opencv_imgproc opencv_highgui opencv_features2d WRAP python)

ocv_warnings_disable(CMAKE_CXX_FLAGS -Woverloaded-virtual)


ts 모듈은 opencv 모듈들의 정상 동작을 테스트하기 위한 모듈이기 때문에 굳이 world 모듈에 같이 포함하여 빌드할 필요는 없다 (별도 dll 파일로 빌드하는 것이 바람직하다). 하지만 굳이 world 모듈에 포함하여 빌드하고 싶으면 opencv\modules\ts\CMakeList.txt를 열어서 다음의 두 줄을 주석 처리한다.


#set(OPENCV_MODULE_TYPE STATIC)

#set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)


마지막으로 dnn의 경우에는 world에 함께 포함시킬 방법을 찾지 못하였다. 꼭 필요한 경우에는 dnn\cMakeList.txt를 수정해서 방법을 찾아볼 수도 있겠지만 굳이 world 모듈에 포함시킬 필요는 없을 것 같다.



Step 4. OpenCV 프로젝트 생성하기


앞서와 같이 cmake configuration이 모두 끝났다면 generate 버튼을 눌러서  build할 프로젝트를 생성한다.



Step 5. OpenCV 빌드하기


마지막 과정으로, 빌드 폴더에 생성된 OpenCV.sln 파일을 열어서 Visual Studio로 컴파일을 해 보면 수 많은 에러 메시지들을 볼 수 있다 (ㅠ.ㅠ). 예를 들어 xfeatures2d에서 다음과 같은 에러 메시지가 출력될 것이다.


opencv-master\modules\xfeatures2d\src\pct_signatures\distance.hpp(195): error C2653: 'PCTSignatures' : is not a class or namespace name (D:\Downloads\opencv-master\modules\xfeatures2d\src\pct_signatures\pct_clusterizer.cpp)


이러한 문제는 xfeatures2d처럼 모듈의 src 폴더 밑에 별도의 하위 폴더가 존재할 경우에 발생한다 (xfeatures2d는 src\pct_signatures 폴더가 존재). 하위 폴더에 있는 *.cpp 파일을 컴파일할 때 precomp.hpp 파일을 해당 모듈의 파일이 아닌 엉뚱한 path 상의 파일을 읽어들이면서 발생하는 문제이다. 이 문제가 왜 발생하는지는 잘 모르겠지만 해결책은 간단하다. 해당 모듈의 precomp.hpp 파일을 하위 폴더에 복사해서 넣어주면 된다.

  • xfeatures2d\src\precomp.hpp 파일을 xfeatures2d\src\pct_signatures\로 복사
  • saliency\src\precomp.hpp 파일을 saliency\src\BING\로 복사

이후 컴파일을 진행하면 에러없이 정상 빌드된다 (다운받은 opencv 버전에 따라서 xfeatures2d, saliency 이외 모듈에서도 에러가 발생할 경우에 유사하게 처리해 준다)


이상으로 모든 과정을 완료하였고 빌드 후 결과 폴더에 가 보면 모든 opencv 모듈들이 하나의 world 파일로 합쳐진 것을 확인할 수 있다 (opencv_world310.dll과 opencv_world310.lib).


☞ 보면 문제들이 대부분 path 설정과 관련된 문제들인데, cmake 쪽을 잘 모르다 보니 그냥 땜빵으로 문제를 해결하였습니다. make 파일을 다루시는 분이라면 아마도 좀더 효과적으로 처리하는 방법이 있을 것 같습니다.


by 다크 프로그래머


저작자 표시 비영리 변경 금지
신고
  • BlogIcon NeoDreamer 2016.11.24 09:26 신고 ADDR 수정/삭제 답글

    저도 찾고 있던 정보였는데 이렇게 알게되네요. 좋은 정보 감사드립니다.

  • sanzarak 2016.12.28 10:25 신고 ADDR 수정/삭제 답글

    항상 좋은 정보 감사드립니다.
    그런데 Opencv 3.1 과 3.2 버전에서 TBB 까지는 하나의 world파일 생성이 되는데
    Cuda (WITH_CUDA, WITH_CUFFT)를 적용해서 컴파일하면 에러가 나는데 혹시 이유를 알고계시거나 해결 경험이 있으신지요. 쿠다툴킷은 cuda_8.0.44_windows7 을 사용했습니다.

    • BlogIcon 다크pgmr 2016.12.30 08:24 신고 수정/삭제

      쿠다로는 해보지 않아서 잘 모르겠습니다.

  • 타이곤 2017.01.04 22:00 신고 ADDR 수정/삭제 답글

    좋은 글 감사합니다. 새해 복 많이 받으세요~~

    • BlogIcon 다크pgmr 2017.01.04 22:36 신고 수정/삭제

      아 네.. 뭔가 답변을 달려고 하던 중에 내용이 바뀌었네요. 어쨌든 해결이 되신 모양입니다 ^^

  • 타이곤 2017.01.05 08:53 신고 ADDR 수정/삭제 답글

    아~~ 보시고 계셨군요. 중간에 에러부분이 달라서 글을 쓰다가 BUILD_opencv_dnn 체크를 빼고 하니 위의 글과 내용이 같아져서 내용을 삭제했습니다. 돌 다리도 두들겨 보고 건너라는 옛말이 맞네요.
    늘 좋은 글 많이 올려주셔서 감사드리고 관심가져 주셔서 또 한번 감사드립니다.

  • 타이곤 2017.01.10 16:30 신고 ADDR 수정/삭제 답글

    OpenCV 3.2(최신버전)과 contrib 최신 버전 설치 후 waitKey() 함수를 이용하여 방향키 입력 시 기능을 구현하려 했더니 작동이 되질 않습니다.

    int iKey = waitKey(1);
    if (iKey == 0x250000) { x -= 10; }

    이렇게 해보니 입력이 들어오질 않습니다. 2.4.13 / 3.1.0 버전은 작동을 합니다. 3.2.0 버전의 버그일까요? 그렇다면
    3.1.0 버전에서 이 버전과 호환(?)되는 contrib를 사용할 수 있는 방법이 있을 까요?
    3.1.0 Release(Opencv.org) 버전과 github에서 contrib를 다운받아 Youtube에 황선규 교수가 올리신 동영상과 다크님의 방법으로 컴파일 했더니 에러가 많이 나오네요

    동영상 : https://www.youtube.com/watch?v=ptvnUCT7wEQ

    그냥 2.4.13 버전을 사용하는 것이 나을 까요?

  • opencv 2017.01.12 14:57 신고 ADDR 수정/삭제 답글

    다크님 덕분에 최근에 항상 많은 도움을 얻고 있습니다!!

    근데 여기서 궁금한게 있는데 step3에서 cmake를 실행하라는게 어떻게 실행하라는 말인가요..?

    • BlogIcon 다크pgmr 2017.01.12 15:47 신고 수정/삭제

      다운받은 cmake 실행파일을 마우스로 더블 클릭하시면 ...

    • opencv 2017.01.13 16:35 신고 수정/삭제

      제가 바보였네요...
      감사합니다!!

  • 2017.01.12 21:22 신고 ADDR 수정/삭제 답글

    ximporc 에러가 나서 설명대로 주석 처리한 뒤 다시 configuration 했더니

    Bad modules: opencv_dnn;opencv_tracking;opencv_world
    Call Stack (most recent call first):
    cmake/OpenCVModule.cmake:509 (__ocv_sort_modules_by_deps)
    cmake/OpenCVModule.cmake:302 (__ocv_resolve_dependencies)
    modules/CMakeLists.txt:7 (ocv_glob_modules)

    이와 같은 에러가 뜹니다. 혹시 조언을 구할 수 있을까요ㅜㅜ

    • BlogIcon 다크pgmr 2017.01.13 16:06 신고 수정/삭제

      git에 있는 내용들이 계속 업데이트되기 때문에 에러는 다운받은 버전에 따라 달라질 수 있습니다.. 그리고 다른 사람이 원인을 알기는 어려우니 위 해결 예제를 참고하셔서 여러 시도를 해 보시면 좋을 것 같습니다. 일단 에러가 나는 모듈들의 CMakeList.txt 파일을 확인해 보시고 제가 시도했던 방법들을 참고해서 여러 방법을 시도해 보시기 바랍니다.

    • opencv 2017.01.13 16:37 신고 수정/삭제

      핑님 혹시 해결하셨나요...
      저도 계속 같은문제가 발생해서 그런데 해결하셨으면 도움을 좀 부탁드립니다 ㅠㅠ

  • opencv 2 2017.01.16 16:38 신고 ADDR 수정/삭제 답글

    CMake Error at modules/text/CMakeLists.txt:22 (ocv_add_testdata):
    Unknown CMake command "ocv_add_testdata".

    이 에러는 무엇인가요?..

  • 스냑 2017.02.23 15:56 신고 ADDR 수정/삭제 답글

    자료 감사합니다. 지금 열심히 따라하는 중인데요,,
    하나 궁금한 것이 있는데 소스코드 다운받은 것은 버전 3.0인가요 3.1인가요
    지금 윈도우 32bit visual 2010 환경에서 개발중인데 정상적으로 사용 가능한지 궁금합니다.

    • BlogIcon 다크pgmr 2017.02.23 17:52 신고 수정/삭제

      3.1이긴 한데, release 버전을 받은게 아니라 git에서 당시 가장 최신 코드를 받아서 버전을 말하긴 애매합니다. 3.1보다는 약간 더 나아간 버전입니다. 그리고 저는 visual studio 2013에서 빌드해서 2010 버전에 대해서는 모릅니다. 하지만 vs 버전은 큰 관계없지 않을까요?

    • 스냑 2017.03.02 09:23 신고 수정/삭제

      지금 다운로드 되는건 3.2 버전이네요.. 결국 64비트 os 새로 깔아서 해결했어요! 감사합니다.



티스토리 툴바