관리 메뉴

악보쓰는 프로그래머

OpenCV 책 출간 본문

My Life

OpenCV 책 출간

dltpdn@gmail.com 이세우 2019. 4. 14. 15:12

제가 OpenCV를 주제로 하는 책을 출간했습니다.

제목은 “파이썬으로 만드는 OpenCV 프로젝트, 간단한 영상 입출력부터 머신러닝까지” 입니다.


책은 이미 온오프라인 서점에서 구매할 수 있습니다.

제 첫 출판 서적이라서 매우 고무되어있습니다.

많은 저자들이 스스로 자기 책을 “졸저”라고 말하는 경우가 많은데요, 
예전에는 저는 그걸 이해하지 못했어요.
얼마나 대충 썼으면 스스로 졸저라고 하느냐는 생각이었는데요,
제가 직접 책을 내고 보니 졸저라고 하지 않을 수 가 없네요.

원고의 뒷 부분을  써가다 보면 앞 부분을 수정하고 싶을 때가 많은데, 그럼 원고 전체의 틀이 달라 지기 때문에 일이 너무 많아 지는 경우도 있는데 시간에 쫓기다 보니 바꾸고 싶은 곳을 손대는 것을 포기하는 경우가 있습니다.

또, 어떤 주제를 설명하는 글이 한번 매끄럽지 못하면 나중에 아무리 다시 고쳐도 마음에 들지 않는 경우도 있습니다.

이런 부분은 베타리더들께서 어김없이 꼬집어 내더군요. 그런걸 보면 제가 스스로 마음에 들지 않아 하는 부분은 대부분의 사람들도 비슷하게 느끼는것 같습니다.

이 책은 최대한 쉽게 설명하려는 것을 목적으로 했고, 단순히 개별적인 기술을 설명하고 마는 것이 아니라 한 프로젝트에 적용할 수 있는 실용적인 코드를 만들어 보는 것을 목표로 했습니다.

어쨌든 제 첫책인 만큼 많은 사람들에게 읽혀 졌으면 하는 바램은 매우 큽니다. 많은 관심 부탁 드립니다.





'My Life' 카테고리의 다른 글

OpenCV 책 출간  (24) 2019.04.14
2013년을 보내며...  (2) 2014.01.02
우리집, 땅콩집과 땅콩 마을을 소개합니다.  (27) 2013.05.15
왼쪽에 나오는 광고에 대한 변  (11) 2012.02.22
금주 30일 도전  (4) 2009.02.23
24 Comments
  • 프로필사진 나기용 2019.05.01 19:51 책을 사서 읽고 있는데 제가 라즈베리가 아닌 Nvidia Jetson nano에서 사용하려는데

    Opencv가 3.3.1일 설치되어 있어서 책을 보고 3.4로 업데이트를 하려는데 막혀서 애를 먹고 있습니다.ㅠㅠ
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2019.06.13 16:12 신고 Nvidia Jetson에서는 해당 CPU에 맞게 빌드된 OpenCV 버전을 사용해야 합니다.
  • 프로필사진 허종덕 2019.05.11 23:45 안녕하세요? "파이썬으로 만드는 OpenCV 프로젝트" 책자를 교보문고를 통해 구입했습니다.
    예제코드 다운로드를 통해 다운로드를 받을 수 있다고 하셨는데, 접속하니 에러가 발생하여
    다운로드가 안됩니다. 저의 멜주소는 jdheo777@naver.com입니다.
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2019.06.13 16:11 신고 책에서 설명한 대로 https://github.com/dltpdn/insightbook.opencv_project_python 에서 다운로드 받으실 수 있습니다.
  • 프로필사진 sonic 2019.08.16 10:27 안녕하세요 선생님.
    제가 스마트폰 카메라로 손을 실시간으로 인식하여 증강현실(AR)에 띄어진 객체를 선택 및 이동시키려고 하는데요. 선생님 책을 공부하면 실현 가능할까요?
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2019.09.16 11:18 신고 안녕하세요? 제 책으로 문의 하신 과제를 수행하는데 필요한 기반 지식은 습득하실 수 있지만, 그 자체를 해결할 수는 없습니다.
  • 프로필사진 NeuRobo 2019.09.18 12:22 308페이지의 cv2.T_CCOEFF 수식 2번째 수식이 오류가 있는 것 같습니다.
    T'(x', y') = T'(x', y') - 1/ ... 로 되어 있는데,
    T'(x', y') = T(x', y') - 1/ ... 로 변경되어야 할 것을 보입니다.
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2019.11.15 14:10 신고 감사합니다.
  • 프로필사진 Jisuk 2019.12.20 16:33 안녕하세요 :) OpenCV 책으로 막 공부를 시작하던 중 궁금한 점이 생겨 질문할곳을 좀 찾고 있었는데.. 여기에다 해도 되는지 모르겠네요^^;; 2장의 웹캠 리사이징하는 예제인 video_cam_resize.py 를 실행하면 아래와 같은 에러가 발생하고 아무런 창이 뜨지 않습니다. video_cam.py는 잘 돌아가서 resize 부분만 주석처리하니 실행이 되네요. 사용하는 웸캠은 Logitech HD720p 인데, 혹시 리사이즈 명령을 하면 프레임을 가져오는데 문제가 생기는 걸까요..?

    PS D:\openCV> ${env:PTVSD_SESSION_ID}='1'; ${env:PTVSD_LAUNCHER_PORT}='59116'; & 'C:\Users\Jisuk\AppData\Local\Programs\Python\Python37-32\python.exe' 'c:\Users\Jisuk\.vscode\extensions\ms-python.python-2019.11.50794\pythonFiles\lib\python\new_ptvsd\wheels\ptvsd\launcher' 'd:\openCV\insightbook.opencv_project_python-master\02.interface\video_cam_resize.py'
    Original width: 640, height: 480
    Resized width: 320, height: 240
    [ WARN:0] videoio(MSMF): OnReadSample() is called with error status: -1072875855
    no frame![ WARN:0] videoio(MSMF): async ReadSample() call is failed with error status: -1072875855
    [ WARN:1] videoio(MSMF): can't grab frame. Error: -1072875855
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2020.01.07 11:15 신고 프레임 사이즈를 바꾸는 cap.set(cv2.CAP_PROP_FRAME_WIDTH 또는 HEIGT) 함수에서 오류가 발생하는 것으로 보입니다.

    카메라 마다 aspect ratio를 지원하는 스펙이 달라서 생기는 문제로 이해하고 있지만, 같은 코드를 서로 다른 OpenCV 버전에서 실행해도 비슷한 문제가 발생하는 현상이 있습니다.
    결론은 저도 정확히 원인을 파악하기 어렵습니다.

    Width, height 비율을 여러가지로 변경해서 시도 해보시면 될겁니다.
    예를 들어 width : 480, height: 320 처럼요.

    명확한 답변을 드리지 못해 죄송합니다.
  • 프로필사진 jyh 2020.01.15 16:06 책 구매자입니다.
    예제를 따라하다가 웹캠으로 동영상 저장시 FPS값을 임의로 설정하는 부분이 있습니다.
    그러다보니 결과물이 실제 속도보다 빠르거나 늦은 경우가 있습니다. 결국 프레임을 추측하여 값을 넣어야 하는데 정확한 프레임 값을 얻기 위해서는 어떻게 해야 하는지 궁금합니다.
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2020.02.06 14:34 신고 1. 웹캠의 정확한 FPS 얻기
    OpenCV 버전과 웹캠 제품에 따라 FPS를 얻을 수 있는 지가 결정됩니다.
    제가 모든 웹캠 제품에 대해 실험해 보지는 않아서 정확하지는 않지만 책에서 설명한 OpenCV 3.4 버전에서는 웹캠의 FPS를 얻을 수 없었고
    그 이후 버전에서 부터는 몇몇 웹캠 제품에 따라 FPS를 얻을 수 있습니다.
    FPS를 얻는 코드는 아래와 같습니다.

    cap = cv2.VideoCapture(0)
    fps = cap.get(cv2.CAP_PROP_FPS)

    2. 동영상 저장 시 실제 속도와 다른 경우
    우선, 동영상을 저장할 때 FPS를 지정하는 것은 웹캠의 FPS와는 별개의 문제입니다.
    웹캠의 FPS는 "초당 몇 프레임을 촬영할 수 있는가" 이고,
    동영상의 FPS는 "초당 몇 프레임을 저장하는가" 이기 때문입니다.

    따라서 원하는 동영상의 FPS를 임의로 설정해서 저장해도 상관없습니다.
    그럼에도 불구하고 실제로 동영상을 실행해보면 속도가 빠른것으로 나타날것입니다.(실행 속도가 빠른것은 촬영한 속도가 느린것입니다.)
    그 이유는 지정한 FPS와 실제 저장하는 프레임수가 정확히 일치하지 않기 때문입니다.
    FPS에 맞게 저장하기 위해서는 cv2.waitKey() 함수를 이용해서 원하는 FPS에 맞게 조정해야 하는데
    정확히 계산해서 조정해도 cap.read() 함수와 writer.write() 함수 사이에 일정한 시간이 소모 되기 때문에
    정확한 시간을 계산해서 저장하는 것이 어렵습니다.
    따라서 이 경우 저장하는 기능만 별도의 쓰레드로 구현해야 합니다.
    하지만 그마저도 멀티 프로세스가 동작하는 운영체제를 사용하는 PC에서는 완전히 정확하게 저장하기 어렵습니다.
    그래서 스레드를 이용해서 저장해도 약간의 속도 차이는 날 수 밖에 없습니다.
    따라서 완전히 정확한 FPS로 저장하려면 카메라나 비디오 캠코더 처럼 오직 촬영 및 저장 작업만 하는 전용 촬영 장비를 사용할때 가능합니다.

    결론적으로 정리하자면 완전히 실제 속도와 같은 FPS로 저장하는 것은 멀티 프로세를 지원하는 운영체제를 사용하는 컴퓨터에서는 불가능하고
    최대한 비슷하게 하려면 쓰레드로 코딩하셔야 합니다.

    코드를 손쉽게 작성하면서도 사람이 인지하는 선에서 크게 차이가 나지 않는 속도로 저장하려면
    FPS를 정할때 1000/fps 를 계산할때 정수로 떨어지는 FPS를 정하는 것이 좋습니다. 예를 들면 25fps 정도입니다.

    아래 링크는 25fps로 저장하는 코드 입니다.
    https://github.com/dltpdn/opencv-python_edu/blob/master/02.interface/video_cam_rec.py
  • 프로필사진 jyh 2020.01.23 00:43 안녕하세요. 책 구매자입니다.
    질문이 있어서 댓글남깁니다.
    -------------------------------------------
    1. IMREAD_GRAYSCALE로 불러온 이미지는 1채널이기 때문에
    그냥 imshow 로 출력하면 안되는 것 같다.(imshow는 기본 GBR모드로 출력하기 때문에)
    따라서
    plt.imshow(value,cmap='gray')
    이렇게 출력해야 제대로 나오는 것 같다.
    그러면
    COLOR_BGR2YUV로 변환된 배열도 바로 출력 할 수 있는 모드 값이 있는지? ex)imshow(value,cmap='yuv')

    (*중요하지 않은 질문)
    위의 경우(그래이모드로 변환)에서 imshow 할 때 cmap='gray' 를 넣지 않으면 나머지 값에 컬러색상이 나오던데 이유가 궁금합니다.(사전에 0으로 초기화 함)

    2. [그림 4-15]에서 THRESH_TRUNC 모드 결과 그림이 이해가 잘 가지 않습니다.
    임계점 이하 값이 본래 값으로 설정된다면 임계점 이하 부분은 오리지널 부분과 동일해야 하는데 오리지널이 압축된 모습입니다.

    THRESH_TOZERO는 오리지널 부분과 동일하게 보입니다.

    THRESH_TOZERO_INV 역시 압축되어 나타나는 모습니다.

    제가 무언가 이해를 잘못하고 있나요?

    또, 세번째 인자로 0값을 설정하여도 변함없이 흰색으로 나타나는 이유도 궁금합니다.





    ===================
    질문을 주고받는 게시판같은 것을 개설해주시면 다른 사람이 답변해주거나 기존의 답변을 볼 수 있을 것 같습니다.
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2020.02.06 15:04 신고 1. IMREAD_GRAYSCALE로 불러온 이미지를 cv2.imshow로 출력하는데는 아무 문제가 없습니다. 그런 사례는 책에도 많습니다.
    아래 링크를 확인해 보세요.

    https://github.com/dltpdn/insightbook.opencv_project_python/blob/master/02.interface/img_show_gray.py

    다만 plt.imshow()의 경우 기본이 RGB로 출력하기 때문에 이상한 색상이 출력되고 그것이 싫으면 cmap="gray" 속성으로 이미 정의된 gray 컬러맵을 사용하는 것입니다.

    COLOR_BGR2YUV로 변환된 이미지는 cv2.imshow(), plt.imshow() 어떤 함수를 쓰든간에 정상적인 색상을 시각화 하실 수 없습니다. 그저 있는 그대로의 값을BGR 또는 RGB로 해석하게 만들어져 있기 때문입니다.

    2. [그림 4-15]이 설명과 다른 이유는 2가지 입니다.
    첫째, 그림을 출력할때 cv2.imshow()가 아닌 plt.imshow() 함수를 사용했습니다. 이때 plt.imshow(value, cmap='gray') 처럼 cmap='gray' 옵션을 사용하는 경우, 이 함수는 value 배열의 가장 작은 값을 0으로 가장 큰 값을 255로 정규화해서 출력하는 특성이 있습니다. 그래서 마치 전체 그림이 압축된 것 처럼 표시되었습니다. 미리 알아 채지 못한점 사과 드립니다.
    [예제 4-10]의 for 구문을 시작으로 끝까지 아래 코드 처럼 바꾸어 실행 하시면 정확한 결과를 보실 수 있습니다.
    #아래 코드에 들여쓰기가 표시되지 않은것을 감안해 주세요.
    for i, (key, value) in enumerate(imgs.items()):
    cv2.imshow(key, value)
    if i==3:
    print(value[-1, -1])

    cv2.waitKey()
    cv2.destroyAllWindows()


    둘째, cv2.THRESH_TRUNC 에 대한 설명이 틀렸습니다.
    책에서는 아래와 같이 설명하고 있습니다.
    px > threshold ? value : px

    하지만 정확하게는 아래와 같이 설명하는 것이 옳습니다.

    px > threshold ? threshod : px

    따라서 TUNC의 경우 위 코드로 수정해서 실행해도 [그림 4-15]와 다르게 왼쪽 절반은 원래의 그림이 나타나고 오른쪽 절반은 회색(127)으로 채워진 그림이 나타나게 됩니다.
    오류가 있는 설명에 대해 다시한번 사과 드립니다.
    그리고 좋은 질문 감사합니다.
  • 프로필사진 jyh 2020.02.08 19:32 안녕하세요.
    지난 답변 감사합니다.

    새 질문이 있어서 글 남깁니다.
    -------------------------------------
    예제 4-32

    bp = np.minimum(bp, 1) : 비율이라 1이 넘지 않도록 처리해 주는 것인데 애초에 1이 넘는 상황이 있는지??
    =>1이 넘으려면 오리지널 히스토그램 특정 좌표값보다 관심영역(roi) 히스토그램 특정 좌표값이 더 커야 하는데 이러한 경우가 발생 할 수 있나요? 혹시 모를 경우를 대비해서 처리하는 것인지 아니면 제가 단순히 코드를 잘못 해석한 것인지 궁금합니다.(혹시 모를 경우가 있다면 어떤 상황에서 발생 할 수 있나요?)

    (책167 'np.ninum'=>'np.ninimum' 정정해야 하는 것 같습니다.)


  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2020.02.20 09:56 신고 안녕하세요? 좋은 질문을 지속적으로 올려 주셔서 대단히 감사합니다.

    질문에 대한 결론을 먼저 말씀드리자면 np.minimum() 코드는 필요하지 않습니다.

    이론적으로 roi_hist/img_hist 이기 때문에 전체 이미지의 일부분 히스토그램이 전체 이미지의 히스토그램 보다 클 수 없기 때문에 가분수 꼴이 나오는 항목이 전혀 없어서 1보다 큰 값은 존재 할 수 없는 것이 맞습니다. 따라서 해당 코드는 불필요합니다.

    하지만, 예제 4-32에서 해당 코드를 지운것과 그렇지 않은 것의 결과는 미세한 차이를 보입니다. 그 이유는 예제 코드에 제가 실수한 부분이 있기 때문입니다. ROI를 선택하고 빨강 사각형을 표시해 두는 데 그 사각형이 칠해진 이미지를 ROI 이미지로 사용하는 실수가 있습니다. 이것 때문에 원인을 찾지 않고 예제를 작성하면서 np.mininum() 코드를 억지로 넣어서 해결하고나서 나중에 원인을 해결할 것을 잊은것 같습니다.

    실수한 코드는 아래와 같이 변경되어야 합니다.(들여쓰기가 표현되지 않으니 유의해주세요.)

    # ROI 선택 ---①
    (x,y,w,h) = cv2.selectROI(win_name, img, False)
    if w > 0 and h > 0:
    #roi = draw[y:y+h, x:x+w] #실수
    roi = img[y:y+h, x:x+w] # 정정


    그럼 또 궁금한것 있으면 언제든 질문해 주세요.
  • 프로필사진 김시조 2020.03.10 11:34 안녕하세요?
    학부 3학년 전자공학과
    Digital image processing 강좌
    Textbook으로 선정하여 이번 1학기에 사용하고자 하는데
    관련 서적에 대한 강의자료 있으시면
    sjkim@anu.ac.kr 로 부탁드립니다.
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2020.03.11 12:29 신고 email로 답변드렸습니다. 교재로 선정해 주셔서 대단히 고맙습니다.
  • 프로필사진 want2bfree 2020.04.18 15:35 안녕하세요,
    좋은 책으로 재미있게 공부하고 있는 1인입니다.
    제가 잘못 이해하고 있는 것인지 모르겠지만,
    공부하면서 이상한 부분이 있어서 여쭤봅니다.

    =============================================

    196페이지에서 remap 함수를 설명하실 때,
    mapx[0][0]=10, mapy[0][0]=5가
    src의 (0, 0)에 있는 픽셀을 dst의 (10, 5)로 옮기라는 뜻으로 설명해 주셨습니다.

    그런데 OpenCV 문서를 보면
    dst(x, y) = src(f_x(x, y), f_y(x,y))라고 되어 있습니다.
    이에 따르면
    dst(0, 0) = src(f_x(0,0), f_y(0, 0)) = src(10, 5),
    즉 src의 (10, 5)에 있는 픽셀을 dst(0, 0)으로 옮기라는 뜻이고,
    몇 가지 실험을 해봐도 그렇게 나오는 것 같습니다.
    사실 이 부분은 볼록/오목 렌즈 왜곡 효과에서 exp에 대한 설명에 의문이 생겨서 찾아본 것입니다.

    제가 착각하고 있는 것인가요? 설명 부탁 드립니다.

    감사합니다.
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2020.04.27 10:51 신고 죄송합니다. 제가 잘 못 설명했습니다.

    말씀 하신대로 mapx, mapy가 갖는 값은 src의 remap 전 위치이고 mapx,mapy의 인덱스가 remap 후 위치입니다.

    따라서,
    mapx[0][0] = 10, mapy[0][0] = 5 일때
    src(10,5)를 dst(0,0)으로 옮기라는 결과가 옳습니다.

    혼란을 드려서 죄송합니다.
    덕분에 책의 중요한 오류를 알게되었습니다. 감사합니다.
  • 프로필사진 CityRock 2020.04.21 09:06 헐 tpu 글 보고 있었는데 내가 보던책 작가시라니 ㄷㄷㄷ
    잘 보고 있습니다., 감사합니다.
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2020.04.27 10:51 신고 감사합니다.
  • 프로필사진 OpencvNoob 2020.06.03 22:56 안녕하세요! opencv2를 이번 이세우선생님의 책을 통하여 배우고 있는 사람입니다.
    139쪽 맨아래에 큰 오류는 아닌데 오타가 있어서 알려드립니다 ㅎㅎ
    img1[:, :200] = 255 #왼쪽은 검은색(0), 오른쪽은 흰색(255)
    를 -> #왼쪽은 흰색(255), 오른쪽은 검은색(0)로 고쳐야 할 것 같습니다.
  • 프로필사진 Favicon of https://blog.xcoda.net BlogIcon dltpdn@gmail.com 이세우 2020.06.08 23:30 신고 감사합니다. 생각보다 오타가 너무 많네요.
    다음 인쇄판에 꼭 적용하겠습니다.
댓글쓰기 폼