반응형

개요

ubuntu 20.04 LTS 에서 OpenCV C++ 기본 빌드 환경에 대해서 샘플로 작성한 포스트. 해당 샘플은 카메라로 받은 이미지를 OpenCV imshow() 를 통해서 보여준다.

기본 틀이기 때문에 처음에는 복붙으로 확인이후 자신이 개발하고자 하는 것에 맞춰서 수정해 나가면 된다. 물론 makefile 기반이다.

굳이 camera 코드를 샘플로 작성한 이유는 임베디드 환경에서 카메라 다루게 되는 경우 성능상 C++을 써야 하기 때문이다. 특별한 이유가 없다면 가능하면 그냥 opencv-python 을 사용하자(하지만 제품을 만들려면 저사양 고성능을 뽑아야 하느라 삽질하겠지).

makefile sample

makefile 에 대해서 배운적이 없다면 복붙전에 읽어보고 사용하는 것이 좋다. 파일명은 반드시 makefile로 지어야 한다.  make clean 을 할 경우 규칙에 의해서 빌드 결과와 실행 파일이 삭제 되도록 되어 있다.

# Makefile
CPPFLAGS = -std=c++14 $(shell pkg-config --cflags opencv4)
LDLIBS = $(shell pkg-config --libs opencv4)
# source file name
OBJS = webcam_sample.o
# result execute file name
TARGET = test

all: $(TARGET)

$(TARGET): $(OBJS)
	g++ $(CPPFLAGS) -o $@ $< $(LDLIBS)

clean:
	rm -f *.o
	rm -f $(TARGET)

camera sample code

널리 알려져 있는 camera sample code에서 실행시 카메라 번호를 수정할 수 있도록 약간만 수정한 소스코드이다. 

// webcam_sample.cc
#include <opencv4/opencv2/videoio.hpp>
#include <opencv4/opencv2/highgui.hpp>
#include <iostream>
#include <string>

bool is_number(const std::string& s)
{
// 
    return !s.empty() && std::find_if(s.begin(), 
        s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end();
}

int main(int argc, char** argv)
{
    int cam_num = 0;
    if (2 == argc) {
        auto camNumParam = std::string(argc[1]);
        if (is_number(camNumParam)) {
            cam_num = std::atoi(camNumParam);
        }
    }

    cv::VideoCapture cap(cam_num);
    if(!cap.isOpened()) {
        std::cout << "did not open camera" << std::endl;
        return -1;
    }
    cv::Mat frame;
    while(1)
    {
        cap >> frame;
        cv::imshow("Camera Capture", frame);
        if (cv::waitKey(30) >= 0)
        {
            break;
        }
    }
    return 0;
}

카메라 장치 다룰때 주의사항

우분투는 먼저 인식한 카메라 장치 순으로 번호를 부여한다. 일반적으로 웹에 돌아다니는 예제는 0번으로 되어 있지만, 노트북같은 환경에서 usb 카메라를 붙이면, 노트북 기본 카메라가 0번, usb web cam은 1번으로 잡히게 된다.

또한 다른 프로그램에서 카메라를 점유(사용)하고 있을 경우에는 다른 프로그램에서 접근을 할 수 없다.

반응형

'Computer Vision' 카테고리의 다른 글

Computer Vision 이미지 자료형  (0) 2024.01.18
Ubuntu 20.04 OpenCV 4.x + cuDNN 설치  (0) 2023.04.26
반응형

OpenCV로 끊김이 적은 동영상 재생

코드

배경이야기가 너무 길어서 두괄식으로 본론인 코드를 먼저 기록한다.

import cv2
import time
import ipywidgets as widgets
import IPython.display as display
import copy

cap = cv2.VideoCapture(video_file)
wImg = widgets.Image(
    layout = widgets.Layout(border="solid")
)
display.display( wImg)

if cap.isOpened():
    ret, img = cap.read()
    while ret:
        # 동영상 파일에서 캡쳐된 이미지를 이미지 파일 스트림으로 다시 인코딩을 한다.
        tmpStream = cv2.imencode(".jpeg", img)[1].tostring()
        wImg.value = tmpStream
        # 20 프레임이 되기 위한 딜레이 다만, 실제로 입력한 것보다 조금 더 딜레이가 있다
        time.sleep(0.05)
        ret, img = cap.read()
cap.release()

배경(도입)

이직을 하고 딥러닝 관련 프로젝트를 하게 되면서 3년만에 IPython notebook을 사용하게 되었다. 지금은 통상 jupyter로 많이 불리기는 하지만, 여전히 IPython notebook의 흔적이 남아 있다. 암튼 jupyter에서는 OpenCV에서 기본적으로 제공하는 imshow()가 정상적으로 작동이 되지 않는다. 이는 초기 OpenCV가 python에서도 동작하게 지원을 할때 독특하게 자체 자료구조인 Mat를 사용하지 않고 numpy.ndarray 자료구조를 사용하게 되면서 IPython Notebook에서 자주 사용하는 matplotlib를 사용하면서 굳이 따로 지원할 필요성을 못 느껴서 그런 것 같다. 게다가 python에 전통적으로 사용하던 IPL 라이브러리 역시 numpy.ndarray구조를 이용하여 이미지 데이터를 관리 하기 때문에 호환도 비교적 쉽다.

OpenCV의 기초인 IO(입출력) 부분에서는 기본적으로 이미지를 화면에 띄우는 것과 동영상을 재생하는 것을 기본적인 과정이다. 이 과정에서 동영상은 여러장의 이미지를 갱신하면서 재생이 된다는 것을 원리로 배울 수 있다. 문제는 matplotlib 의 pyplot 모듈을 이용해서 이미지를 화면에 보여주는데, 이 모듈은 이름에서 볼 수 있듯이 원래는 그래프와 약간이 이미지를 처리하기 위한 모듈이다. 그러다 보니 로컬에서 사용하는 OpenCV에서 처럼 동일한 윈도우에 imshow() 메서드를 호출해서 이미지만 바꿔서 동영상이 재생되는 것을 보여줄 수 없다.

필자는 구글링을 했을 때 스택오버 플로워에서는 다양한 방법들을 제시된 것을 확인 했었는데, 크게 2가지 방법이 있었다. 첫번째 방법은 IPython Notebook에 html 태그 삽입하는 방식을 사용해서 작성하는 방법, 두번째 방법은 webGL 관련 모듈을 설치하여 해당 모듈에 연결하는 방법이다. 필자는 두번째 방법을 시도했었는데, 생각보다. 프래임 드랍이 심했다.

일반적으로 사람이 실시간으로 딜레이를 못느끼는 프래임은 약 20정도인 것을 과거 다른 프로젝트를 통해서 경험을 했었다. 당연히 20프레임 이하였으니 상당한 딜레이를 느꼈던 것이다. 한동안 실망하고 잊고 있었다.

그러던 우연히 ipywidgets 이라는 IPython 자체 지원 모듈중 Image 위젯을 사용해서 이미지를 보는 보조 툴을 만들 일이 있었는데, 생각보다 이미지 파일 전환에 딜레이가 적다는 생각이 들었다. Image 위잿의 파일의 바이너리 스트림을 입력하는 부분에 동영상에서 읽은 이미지를 인코딩을 해서 연속적으로 렌더링을 하게 하면 WebGL보다 부드럽게 이미지 재생이 되지 않을까? 하는 발상으로 테스트를 해보니 생각보다 20프레임 이상 재생이 되는 것을 확인 했었다.

여기서 추가로 테스트 할 점은 코덱을 jpeg 외에 png, bmp 각각 변경해서 시도를 해봤는데, 인코딩시 스트림의 크기 클 수로 느려지는 것을 확인했다. 즉 압축률이 좋을 수록 동영상 재생의 딜레이가 적어지는 것을 알 수 있었다.

반응형
반응형

[python] 버전에 대한 논의와 라이브러리 설치

버전에 대한 (의미없는) 논쟁

 필자가 처음 파이썬을 접하게 된것은 기록시점으로부터 약 4년전인 2014년 말 혹은 2015년 초 쯤 이었다. 당시 필자는 순수 물리학으로 졸업해서 대학원을 컴퓨터 공학으로 전과 지원을 해서 공부를 했기 때문에 이제 막 C/C++와 자료구조를 한참 익히고 있을 때였다.


 그러던 중 멀티미디어 강의를 하고 있던 선배의 부탁으로 실습준비를 도와주면서 파이썬을 처음으로 접하게 되었다. 당시 python3.1이 나오던 시기였기 때문에 대부분 자료는 python2.7을 기준으로 하는 자료가 많았다. 게다가 대부분읜 자료는 윈도우보다는 리눅스나 OS X 기반환경에 대한 설명이 주를 이루었었다. 이는 당시 윈도우 환경에서는 오류가 나는 일이 많았던 것으로 기억이 난다.


 때문에 당시에 규모 있는 커뮤니티에서 2.7 버전과 3.x 버전 중 어느 버전을 사용해야 하느냐는 질문이 나오면 2.x 버전을 사용하는 사람을 게으름뱅이(?)로 취급하는 사람들도 꽤 있었기 때문에 논쟁이 격해지기도 했는데, 의미가 없는 짓이다. 일단 당시 수치계산에 중요한 numpy 라는 라이브러리가 아직 3.x를 완벽하게 지원되지 않았기 때문에 이는 자신이 하려는 일에 지원이 되는지 여부를 확인하고 선택해야 한다.


 물론 지금은 시간이 많이 지나서 기존 2.7에서 지원되는 라이브러리가 3.x에서도 많이 되는것 같다. 특히 pip 같은 라이브러리 관리 툴의 경우 윈도우 환경에서 사용하기 위해서는 별도로 설치 방법을 찾아서 설치를 해주었어야 했으나 지금은 Python 설치시 같이 설치가 된다.



라이브러리 설치

 라이브러리 설치는 이미 Python이 설치되어 있다는 전제하에서 진행을 한다.

 라이브러리를 설치하는 방법은 직접 파일을 다운로드 받아서 설치하는 방법이 있지만, 오프라인 환경에서 작업해야 하는 것이 아닌 이상 pip를 통해서 설치하면 된다. 만약 python2.7 과 python3.x를 같이 혼용해서 사용한다면, -m 옵션을 사용해서 명령어를 실행하면 된다.


예시로 numpy를 설치한다.


# 한가지 버전만 사용하는 경우
pip install numpy

# 두가지 버전을 같이 사용하는 경우 만약 3.x의 경우
python3 -m pip install numpy


 위의 명령어를 powershell 이나 cmd 창에서 실행하면 된다. MS에서는 최근 powershell을 밀고 있으니 powershell을 사용하는 것도 권장한다.

 만약 opencv를 설치할 경우에도 pip를 통해서 설치가 가능하다. 과거에는 python 패키지 관리격인 anaconda를 통해서 설치가 가능했지만, 필자가 이 글을 적는 시점에 확인한 결과 opencv도 설치가 가능했다.


# OpenCV 를 설치하는 경우
# 여기서 matplotlib는 그래프 같은 새창을 띄울때 사용되는 라이브러리이다
python3 -m pip install matplotlib opencv-python

# python3 인터프리터를 호출한후 라이브러리 호출을 확인한다
>>>import cv2
>>>print(cv2.__version__)


대부분 설치 확인을 이미지를 띄워보지만, 버전만 확인해봐도 호출이 제대로 되는지 확인이 된다.


 위의 방식으로 설치할 경우 버전이 최신으로 설치가 되니 버전을 선택을 하고 싶다면, 버전도 추가로 입력을 해줘야 한다. 이처럼 과거보다 python 프로그램의 진입장벽이 많이 낮아 진것이 체감된다. 특히 OpenCV의 경우 C++로 개발하는 것이 아니라면, 이제는 소스를 받아서 CMake로 메타 빌드까지 안해도 되는 시대가 되었다.


참조자료

python opencv 설치 방법



반응형

'Python > Python3' 카테고리의 다른 글

[python3]타입검사(Type Check)  (0) 2019.04.23
[Python3]Str(문자열)의 편리한 기능들  (0) 2019.04.20
[Python3]List의 편리한 기능들  (0) 2019.04.19
[python]CSV 데이터 포멧 입출력  (0) 2018.10.22
[python]기본 Shell 활용  (0) 2018.10.20
반응형

라즈비안 : OpenCV를 쉘 스크립트로 설치

배경

 라즈비안에 OpenCV 설치 하는 방법에 대해서는 사실 많은 블로그에서 정리가 되어 있다. 하지만, 그 과정을 따라서 하는 것도 나쁘지는 않지만, 기본적으로 쉘에서 처리가 가능한 것들은 그냥 쉘 스크립트로 만들면 되지 않을까 하는 생각에서 작성하게 되었다.


 이번글은 작성중인 OpenCV 쉘 스크립트를 저장한 정도의 글이 될 것이다. 이후 추후에 쉘 스크립트 문법에 대해서 정리를 해 놓아야 될 것 같다.



OpenCV 설치 확인 및 제거 방법

 라즈비안이 우분투 커널을 사용하므로 마찬가지로 우분투에서 사용했었을 때 실행이 잘 되었다. 다만, 미리 설치가 되어 있을 경우 제거를 해줘야 한다.


pkg-config --modversion opencv
# 제거할 경우
cd {기본opecv 소스폴더의 build 폴더}
make uninstall


제거를 위와 같이 하지 않으면, apt-get purge로 삭제를 해도 pkg-config으로 검사할때 검출이 된다. 아마도 해당 정보를 지우지 못하는 버그가 있는 것 같다.



OpenCV 설치 쉘 스크립트(contirb포함)

 버전 수준으로 따지자면, 0.1 스크립트라고 봐야 할 것이다. 즉, 아직 부족하다고 생각 든다.

 OpenCV3.2.1외에 다른 버전이 필요한 사람이라면, OPENCV_VERSION의 숫자값을 변경하면 된다. 이미 다른 OpenCV가 설치가 되어 있다면, 설치가 진행되지 않는다. 또한, 일반적인 개발 환경으로 셋팅을 한 것이 기 때문에 실제로 배포를 하려고 할 경우는 필요한것만 빌드하도록 수정해야 한다.


#!/bin/bash

# Custom values
OPENCV_VERSION="3.3.1"
OPENCV_REPO=https://github.com/opencv/opencv/archive/"$OPENCV_VERSION".zip
OPENCVCONTRIB_REPO=https://github.com/opencv/opencv_contrib/archive/"$OPENCV_VERSION".zip

# check exit opencv modules
pkg-config --modversion opencv
if [ "$?" -eq 0 ]; then
  echo "You already install opencv"
  exit 0
fi

# Update Debian
sudo apt-get update && sudo apt-get upgrade -y
if [ "$?" -eq 1 ]; then
  echo "Faile Update or Upgrade"
fi

# Install need modules
DEPPKGS=(build-essential cmake)
DEPPKGS+=(pkg-config)
DEPPKGS+=(libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev)
DEPPKGS+=(libavcodec-dev libavformat-dev libswscale-dev libxvidcore-dev libx264-dev libxine2-dev)
DEPPKGS+=(libv4l-dev v4l-utils)
DEPPKGS+=(libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev)
# Qt4
DEPPKGS+=(libqt4-dev)
DEPPKGS+=(mesa-utils libgl1-mesa-dri libqt4-opengl-dev)
# Optimature lib
DEPPKGS+=(libatlas-base-dev gfortran libeigen3-dev)
DEPPKGS+=(python2.7-dev python3-dev python-numpy python3-numpy)

echo "=== Install depend packages ==="
for DEPPKGNAME in ${DEPPKGS[@]}; do
  dpkg -l | grep "$DEPPKGNAME"
  if [ "$?" -eq 1 ]; then
    sudo apt-get install -y "$DEPPKGNAME"
  fi
done
echo "=== End install depend packages ==="

PWD=`pwd`
WORKSPACE="$PWD"/opencv
if [ ! -d "$WORKSPACE" ]; then
  mkdir "$WORKSPACE"
  cd "$WORKSPACE"
fi

OPENCVZIP="$WORKSPACE"/opencv.zip
if [ ! -f "$OPENCVZIP" ]; then
  wget -O "$OPENCVZIP" "$OPENCV_REPO" \
  && unzip -o "$OPENCVZIP" 
  if [ "$?" -eq 1 ]; then
    echo "fail download '$OPENCVZIP'"
    exit 1
  fi
else
  upzip -o "$OPENCVZIP"
  if [ "$?" -eq 1 ]; then
    echo "fail unzip '$OPENCVZIP'"
    exit 1
  fi
fi

CONTRIBZIP="$WORKSPACE"/opencv_contrib.zip
if [ ! -f "$CONTRIBZIP" ]; then
  wget -O "$CONTRIBZIP" "$OPENCVCONTRIB_REPO" \
  && unzip -o "$CONTRIBZIP"
  if [ "$?" -eq 1 ]; then
    echo "fail download opencv_contrib.zip"
    exit 1
  fi
else
  unzip -o "$CONTRIBZIP"
  if [ "$?" -eq 1 ]; then
    echo "fail unzip '$CONTRIBZIP'"
    exit 1
  fi
fi

# OPENCVDIR="$WORKSPACE"/opencv-3.4.0
OPENCVDIR="$WORKSPACE"/opencv-"$OPENCV_VERSION"
if [ -d "$OPENCVDIR" ]; then
  cd "$OPENCVDIR"
else
  echo "does not have dir '$OPENCVDIR'"
  exit 1
fi

BUILDDIR="$OPENCVDIR"/build
if [ ! -d "$BUILDDIR" ]; then
  mkdir "$BUILDDIR" && cd "$BUILDDIR"
else
  cd "$BUILDDIR"
fi


cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D WITH_TBB=OFF \
-D WITH_IPP=OFF \
-D WITH_1394=OFF \
-D BUILD_WITH_DEBUG_INFO=OFF \
-D BUILD_DOCS=OFF \
-D INSTALL_C_EXAMPLES=ON \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D BUILD_EXAMPLES=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D ENABLE_NEON=ON \
-D WITH_QT=ON \
-D WITH_OPENGL=ON \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-"$OPENCV_VERSION"/modules \
-D WITH_V4L=ON  \
-D WITH_FFMPEG=ON \
-D WITH_XINE=ON \
-D BUILD_NEW_PYTHON_SUPPORT=ON \
../

if [ "$?" -eq 1 ]; then
  echo "fail OpenCV cmake build '$PWD'"
  exit 1
fi

time make
if [ "$?" -eq 1 ]; then
  echo "fail OpenCV make"
  exit 1
fi

# only in raspberry
sudo make install
if [ "$?" -eq 1 ]; then
  echo "fail OpenCV install"
  exit 1
fi

echo "complete OpenCV install"
exit 0




후기

 라즈베리 파이3의 경우 듀얼코어(make 옵션의 -j2)까지는 에러가 발생하지 않지만, 마지막부분에서 문제가 있는지, 싱글코어로 빌드한것과 시간차이가 거의 없었다. 코어를 3개를 올릴 경우 빌드 막바지에서 메모리가 부족해서 빌드가 중단되는 문제가 있다.


 일부 후기에서 정정한다. swap 가상 메모리의 크기를 늘리면, 모든 코어를 빌드에 투입하여 시간을 단축 시킬 수 있다. 방법은 추후에 기회가 되면 정리 하도록 하겠다.


참조 자료

블로그 OpenCV3.4 설치




반응형
반응형

C# OpenCV : nuget을 이용한 OpenCV 개발환경 구축

알게된 배경

C#의 높은 생산성을 알고 나서 OpenCV도 사용할 수 있지 않을까 해서 알아봤는데, 공식 OpenCV에서는 아직 C# 개발환경을 지원하지 않았다. 하지만, C#에서 실행이 가능하도록 옮겨 놓았다는 사실을 알게 되었다.

 친절하게도 오픈소스 설치과정이 어려울까봐 VS의 Nuget 명령어 창을 링크를 걸어줘서 이전과 달리 환경 설정의 부담이 매우 줄게 되었다.


Nuget이란?

비주얼 스튜디오에서 사용되는 오픈소스 프로젝트의 패키지를 관리(PM : Package Management)툴 이다. 프로젝트가 열린 상태에서 실행할 수 있다. 보통 도구 쪽에 잘 찾아보면 있다.


필요한 것

VS2015, OpenCV3.2


주의 할점

 OpenCV의 윈도우 버전 패키지를 다운로드를 받을 때 설치된 폴더의 opencv\build\x64\vc14\bin 이 경로를 환경변수에 등록을 해줘야 한다. 이 때 vc14는 VS2015를 의미하고 vc13은 VS2013 이런식으로 버전을 의미하기 때문에 이를 참고해서 다운로드 받아야 한다.

 현시점에서는 vc14가 최대 지원 버전이기 때문에 VS2015에서 개발을 진행해야 햔다.


 환경변수 잡는 경로는 자신이 압축을 푼 폴더내에서 build\x64\vc14\bin 폴더가 연결되면된다. 이는 실행에 필요한 조건이다. openCvSharp라이브러리만 가지고는 OpenCV를 실행할 수 없는 것으로 보인다.


Nuget으로 openCvSharp 설정잡기

 VS2015를 실행해서 프로젝트를 생성한다. 이후 [도구] -> [Nuget 패키지 관리자] -> [패키지관리자 콘솔] 을 실행하면 하단에 Nuget 커멘드 창이 생성된다.


Install-Package OpenCvSharp3-AnyCPU -Version 3.2.0.20170419


 이후 열심히 개발환경을 셋팅을 해준다. 그리고 테스트용 코드를 사용해보자. 테스트에 사용할 이미지는 마음에 드는 걸로 사용해도 상관없다. 다만, 이미지는 프로젝트 솔루션 내의 Debug(Debug상태에서 설치했으므로)에 넣어주어야 된다.

 설치 커맨드는 정식 github에도 링크가 있고, NuGet에도 있다.

링크 : github OpenCVSharp

링크 : NuGet OpenCVSharp


테스트용 소스코드

프로젝트는 콘솔 앱으로 생성했다.


using OpenCvSharp;

namespace openCvTest01
{
    class Program
    {
        static void Main(string[] args)
        {
            Mat src = new Mat("lena.jpg", ImreadModes.GrayScale);
            Mat dst = new Mat();

            Cv2.Canny(src, dst, 50, 200);
            using (new Window("src image", src))
            using (new Window("dst image", dst))
            {
                Cv2.WaitKey();
            }
        }
    }
}


 만만한게 레나 사진이다(지금도 살아계실지??). 테스트용 소스코드는 github에 저자가 올린 소스코드를 그대로 옮긴 것이다. 정상적으로 2장의 이미지가 보이면 된다.


참고자료

본문중 Github 링크

반응형

'C#' 카테고리의 다른 글

C# 싱글톤 패턴 : 동적 싱글톤  (0) 2017.09.04
C# Socket : 고정 구조체 만들기  (0) 2017.07.11
C# WinForm : 문자 픽셀 측정  (0) 2017.07.06
C# : 콘솔 앱 프로젝트에서 콘솔 감추기  (0) 2017.06.22
C# : 프로퍼티(property)  (0) 2017.01.23

+ Recent posts