'분류 전체보기'에 해당되는 글 1027건

  1. 2016.10.05 (텐서플로우 설치 2)우분투 14.04 tensorflow 설치
  2. 2016.10.05 (텐서플로우 설치 1)우분투 14.04 NVIDIA 그래픽 드라이버 설치 및 cuda, cudnn 설치
  3. 2016.10.05 Windows 10 64bit Theano & Keras 설치방법
  4. 2016.10.05 Windows가 설치된 상태에서 리눅스를 설치하자! (멀티부팅)
  5. 2016.10.05 우분투 Ubuntu 14.04.1 설치
  6. 2016.10.05 Ubuntu우분투 14.04 설치
  7. 2016.09.30 Passing Two or More Inputs or Outputs
  8. 2016.09.30 find_face_landmarks_refsites_20160920
  9. 2016.09.30 Emotion Recognition using Facial Landmarks, Python, DLib and OpenCV
  10. 2016.09.30 Analyzing a Discrete Heart Rate Signal Using Python – Part 3
  11. 2016.09.29 opencv mat를 matlab mex 데이터로 변환할때는 .t()로 transpose시켜줘야 한다.
  12. 2016.09.29 Way to send OpenCV Mat to MATLAB workspace without copying the data?
  13. 2016.09.28 Print out the values of a (Mat) matrix in OpenCV C++
  14. 2016.09.28 Print out the values of a matrix in OpenCV C++
  15. 2016.09.28 Image convert to grayscale
  16. 2016.09.28 DLIB : Training Shape_predictor for 194 landmarks (helen dataset)
  17. 2016.09.23 cmake, visual studio로 mex파일 만들때, INSTALL 프로젝트를 빌드해줘야 생성됨
  18. 2016.09.22 generate MEX-files using Visual Studio
  19. 2016.09.21 [boost] boost build하기
  20. 2016.09.21 [dlib]Compile dlib on Windows
  21. 2016.09.20 [boost] CMake is not able to find BOOST libraries
  22. 2016.09.20 [boost]CMake not finding Boost
  23. 2016.09.19 OpenCV 3.1 개발환경 셋팅
  24. 2016.09.13 OpenCV 3.0 + Visual Studio 2013 으로 컴파일하기
  25. 2016.09.13 mex "example_mex_function.cpp" compile error
  26. 2016.09.13 Matlab에서 Ctrl+C 처리 (utIsInterruptPending)
  27. 2016.09.13 matlab mex memory access
  28. 2016.09.13 How do I link a 64-bit MATLAB mex file to OpenCV libraries
  29. 2016.09.12 dlib to the Windows / Visual Studio environment
  30. 2016.09.08 matlab / python | feature fusion image retrieval / CNN features (5) - 모델 적용 test하는 거 있음

http://flyingdcat4.tistory.com/77

 

 

(Tensor Flow 설치 2)우분투 14.04 tensorflow 설치

 

 

(Tensor Flow 설치 2)우분투 14.04 tensorflow 설치
Tensor Flow 설치 1까지 무사히 성공했다면 이제 본격적으로 tensorflow를 설
치해보자.
아직 ubuntu에 python이 설치되어 있지 않기 때문에 python부터 설치를 한다.
필자는 anaconda를 설치할 것이다. 기본적으로 셋팅되는 라이브러리들이 많
고 conda를 이용하여 개별적으로 셋팅을 관리할 수 있기 때문이다. 우선 anaco
nda 부터 다운로드 받자.
https://www.continuum.io/downloads 로 들어가면 자신의 OS에 맞는 installer를
받을 수 있고 터미널에서 바로 설치를 하자.
sudo bash Anaconda24.1.1Linuxx86_
64.sh
anaconda를 설치하면 home 폴더에 anaconda2가 설치되어 있을 것이다.tensorfl
ow를 설치할 때 폴더 소유권때문에 에러가 나게되는데 이것을 방지하기 위해
서 anaconda2폴더 및 모든 하위폴더의 권한을 현재 계정으로 변경하자.
sudo chown Rc
<계정명>:<계정이속한 그룹> /home/<계정명>/anaconda2
anaconda2폴더로 이동해서 폴더 권한이 현재 계정으로 바뀌었는지 확인한다.
cd anaconda2
ls al
필자의 계정명은 flyingcat4이고 그룹역시 flyingcat4이다. 별다른 설정을 하지
않았으면 계정명이 그룹명이된다. 여기까지 기본셋팅을 하고 라이브러리 dep
endency가 꼬이는 것을 방지하기 위해서 conda를 이용한 가상한경에 tensorflo
w를 셋팅한다. virtualenv랑 똑같다.
conda create n
tensorflow python=2.7
source activate tensorflow
위 명령어까지 실행하면 터미널 라인 맨앞에 (tensorflow)가 생성될 것이다. ten
sorflow환경에서 나오려면
source deactivate
tensorflow 작업환경에서 바로 설치를 한다.

 

pip install --ignore-installed --upgrade https://storage.googleapis.com/te
nsorflow/linux/gpu/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl
anaconda 폴더의 소유권 권한을 바꿨다면 문제없이 설치될 것이다. 설치된 것을 확인하기
위해 터미널에 다음과 같이 입력해보자.
python
import tensorflow as tf
sess = tf.Session()
여기까지 실행해서 GPU이름 나오면서 뭔가 성공적인 메시지들이 보인다면 여러분은 절반정
도 성공한 것이다. 무슨말인지 확인하기 위해서 python환경을 빠져나와서 ipython을 실행해서
똑같은 작업을 해보자.
ipython
import tensorflow as tf
아마 "no module named tensorflow"라는 에러가 출력될 것이다. python에서 되던게 왜 ipython
에서 안되지? jupyter에서는 될까? 하고 똑같이 해봐도 같은 메시지가 출력될 것이다. 하지만
걱정하지 않아도 된다. 필자가 방법을 모르고 포스팅하는것은 아닐테니깐. 그대로 따라하세요
~
conda install ipython
conda install jupyter
tensorflow용 커널을 생성한다.
ipython kernelspec installself
user
mkdir p
~/.ipython/kernels
mv ~/.local/share/jupyter/kernels/python2 ~/.ipython/kernels/tfkernel
여기까지 하면 다된것이다. 다만 jupyter notebook을 켜보면 kernel이름이 구분이 안될텐데 편
의를 위해서 이름을 바꾸자.
cd ~/.ipython/kernels/tfkernel/
vi kernel.json
파일을 열어보면 "display_name"에 설정되어 있는 이름을 자신이 알아볼 수 있도록 변경한다.
필자는 tensorflow kernel이라고 변경하였다.

 

jupyter notebook을 실행시키고 Change kernel에 자신이 생성한 커널이 보이고, 그 커널로 변경
한 후 import tensorflow as tf 를 실행해보자.
더이상 에러메시지가 안나올것이다. 여기까지 했다면 tensorflow 개발환경 셋팅은 완료한 것
이다.

Posted by uniqueone
,
http://flyingdcat4.tistory.com/76

 

 

우분투에 그래픽 드라이버잡는거 그거 뭐라고 만 하루를 꼬박 설치하는데만
보내냐 ㅠㅠ
그때그때 발생하는 에러를 잡기 위해서 구글에 있는 관련 문서는 한글 영어
가리지 않고 거의 다 본것 같다. 본 포스팅은 다시 개발환경을 밀고 설치를 할
때 똑같은 실수를 반복하지 않고, 나와 같은 처지였던 사람들에게 해결방법을
알리기 위함이다. 정말 많은 포스팅이 있는데 볼수록 헷갈리기만 하니까 이포
스팅에서 아주 자세히 설명을 할테니 빠짐없이 그대로 따라하길 바란다.
(1) 사전준비 작업
그동안 정들었던 theano기반 Keras 개발 환경을 과감하게 밀어버리고 tensorflo
w로 넘어가기 위해 우분투 설치 usb를 만들고 일단 그래픽카드를 본체에서 제
거하고 설치를 하자(이유는 질문하면 알려주겠다). 설치 후 네트워크를 연결
하고 NVIDIA 홈페이지에서 그래픽카드 최신버전(내 경우는 64bits 버전 NVI
DIALinuxx86_
64367.44.
run)을 Home 폴더에 다운로드 받자. 내친김에 cuda
와 cudnn도 받아놓자(cuda_7.5.18_linux.run, cudnn7.5linuxx64v5.0ga.
tgz).
그리고 터미널을 켜고 다음 두 명령어를 입력한다.
sudo aptget
update
sudo aptget
install buildessential
(2) nouveau 비활성화
NVIDIA계열 드라이버 설치 시 첫 번째 만나는 난관은 nouveau다. 우분투 설치
시 기본적으로 설치되는 드라이버인데 이녀석이 NVIDIA 드라이버와 충돌을
일으킨다. 자세한 설명은 여기로 (http://blog.neonkid.xyz/66) 요약하자면 nouve
au를 끄고 드라이버를 설치해야한다.
터미널을 실행시키고 다음과 같이 명령어를 입력하면 된다.
sudo vi /etc/modprobe.d/blacklistnouveau.
conf
blacklist nouveau
blacklist lbmnouveau
options nouveau modeset=0
alias nouveau off
alias lbmnouveau
off
:wq를 누르고 저장 후 다시 터미널로 나와서 다음 명령어를 입력한 후 일단 컴퓨터를 끄자.
sudo update-initramfs -u
sudo shutdown -h now
(3) 드라이버 설치
컴퓨터를 끈 후 그래픽 카드를 장착하고 디스플레이를 그래픽 카드로 연결한
다. 그리고 부팅하면 "The system is running in lowgraphics
mode" 라는 처음 맞
이하는 메시지가 나타났다. 처음엔 뭐지 하다가 가만 생각해보니 그래픽카드
드라이버를 설치한 적이 없으니 당연히 low graphics mode로 동작하는거다. 참
고로 내 그래픽카드는 NVIDIA gtx titanX다(갑자기 왠 자랑질??). 침착하게 CT
RL+ALT+F1을 눌러 콘솔로 진입한 다음 로그인을 하자. 다른 포스팅을 보면 li
ghtdm을 stop하라고 되어있는데 아마 지금 상태면 lightdm이 이미 stop되어있

는 상태일 것이다. 그래서 할 필요가 없다. (1)단계에서 받아놓은 드라이버를
바로 설치하면 된다.
sudo sh NVIDIALinuxx86_
64367.44.
run
no하는것 없이 디폴트로 다 설치하자. 설치가 다 되면 다음 명령어를 입력하자
sudo nvidia-xconfig
위에 명령어 입력안하면 x window 실행할 때 xorg관련 problem이 뜰것이다. 그
러니까 까먹지 말자.
여기까지 문제없이 실행했다면 디스플레이 매니저를 실행하자.
sudo service lightdm start
로그인 화면이 뜨고 문제없이 로그인이 될 것이다. 그런데 문제가 하나 있다.
CTRL+ALT+F1을 누르면 콘솔로 넘어가야하는데 아마 까만화면만 뜨고 아무
것도 안나올것이다. 당황하지말고 재부팅 한 후 다음 grub 파일을 수정하면 된
다.
sudo vi /etc/default/grub
파일을 열고 GRUB_CMDLINE_LINUX_DEFAULT="quiet_spolash" 라는 부
분을 아래와 같이 고쳐준다.
GRUB_CMDLINE_LINUX_DEFAULT="quiet_spolash nomodeset"
저장 후 나와서 grub파일을 업데이트 한 후 재부팅 한다.
sudo update-grub
sudo reboot
여기까지 실행하면 드라이버는 깔끔하게 설치된 것이다.
(4) cuda 설치
CTRL+ALT+F1으로 콘솔화면으로 나온 후 로그인한다음에 디스플레이 매니
저를 끄자.
sudo service lightdm stop
(1)에서 다운로드 받았던 cuda 파일을 실행하면 된다.
sudo sh cuda_7.5.18_linux.run
여기서 그래픽 드라이버는 설치했기 때문에 그래픽 드라이버 설치하시겠습니
까(영어로 나온다 잘해석하면 됨)라고 물어보는 질문에는 no, 나머지는 디폴
드로 다 설치하자. 설치 후 bashrc 파일에 cuda 경로를 설정해줘야 한다.
sudo vi ~/.bashrc
위 명령어로 파일을 열어서 마지막에 아래 경로를 추가하면 된다.
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
export CUDA_HOME=/usr/local/cuda
혹시 cuda 설치 시 다음과 같은 에러가 발생한다면 "the driver installation is un
able to locate the kernel source..." 커널을 설치해주면 된다.

 

혹은 다음과 같은 에러가 발생한다면 "You appear to be running an X server..." 프로
세스 관련 폴더를 지우면 된다.
cd /tmp
rm -rf .X0-lock
(참조 http://m.blog.daum.net/goodgodgd/20 의 5.troubleshooting 부분)
(5) cudnn 설치
cudnn 설치는 간단하다. (1)에서 다운로드 받았던 파일의 압축을 풀고 파일을
복사해주면 끝이다.
tar xvzf cudnn-7.5-linux-x64-v5.0-rc.tgz
를 입력하면 압축이 풀리고 Home에 cuda 폴더가 생긴다.
cd cuda/include
sudo cp cudnn.h /usr/local/cuda/include
cd ..
cd lib64
sudo cp libcudnn* /usr/local/cuda/lib64
sudo chmod a+r /usr/local/cuda/lib64/libcudnn*
이제 cudnn까지 설치가 끝났다.
(6) 그 외 설정
cuda를 설치할 때 Home폴더에 nividia sample 폴더가 생성되었을 것이다. 컴파
일 해주자.
cd NVIDIA_CUDA-7.5_Samples/1_Utilities/deviceQuery
make
만약에 make시 에러가 난다면 buildessential이
제대로 설치가 안된 것이므로
(1)의 buildessential을
다시 설치하자. 위 과정까지 끝났으면 제대로 컴파일 되
었는지 테스트를 해본다.
./deviceQuery
실행결과가 PASS이면 제대로 설치된 것이다. 지금까지 수고했다. 마지막 대
망의 확인작업만이 남았다.
nvcc V
nvidiasmi
위 명령어를 실행해서 문제없이 버전과 gpu 스펙을 확인할 수 있다면 마지막
확인 작업이 끝난것이다. 이제 tensorflow 설치준비가 끝났다!

Posted by uniqueone
,
http://flyingdcat4.tistory.com/75

 

 

Window10 64bits Theano&Keras 설치 방법
http://skyer9.tistory.com/7
이 방법대로 설치하면 깔끔함 ㅋ
theano import할 때 아마 cl.exe 찾을 수 없다고 나오는데 이것은 환경변수에 시
스템 path에 설치한 visual studio 2013 path를 추가해주면 해결됨.
내 경우에는 아래 경로로~ (아마 대부분이 비슷한 경로일 거임)
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin

 

Posted by uniqueone
,
http://dsa28s.tistory.com/entry/Windows%EA%B0%80-%EC%84%A4%EC%B9%98%EB%90%9C-%EC%83%81%ED%83%9C%EC%97%90%EC%84%9C-%EB%A6%AC%EB%88%85%EC%8A%A4%EB%A5%BC-%EC%84%A4%EC%B9%98%ED%95%98%EC%9E%90-%EB%A9%80%ED%8B%B0%EB%B6%80%ED%8C%85

 

 

 

 

저번에 리눅스 민트 기반인 하모니카 설치법을 포스팅 했었는데요,

저번 포스팅은 하드디스크에 리눅스만 설치하는 방법이었습니다;;


이번엔 Windows 가 설치된 상태에서 리눅스를 설치하여 Windows와 리눅스를 멀티부팅 하도록 하겠습니다.


설치 전 리눅스 설치 디스크가 필요합니다. 만드는 방법 http://dsa28s.tistory.com/4



필수) Windows 8.1 이상에서는 다음 설정을 해주어야 합니다!


필수 - 1. 제어판 > 전원 옵션에 들어가줍니다.

왼쪽 상단 절전 모드 해제 시 암호 사용을 클릭해주세요.



필수 - 2. 아래 빠른 시작 켜기 체크를 해제해 주세요.

(만약 체크칸이 비활성화 되어있다면 맨 위 현재 사용할 수 없는 설정 변경을 눌러 주신 후 해주세요.)

변경 내용 저장!



1. 리눅스 드라이브를 만들자!


1. 제어판 > 관리도구 > 컴퓨터 관리에 들어가 줍니다.

왼쪽에 디스크 관리를 클릭합니다.


리눅스를 설치할 드라이브를 누르신 후


오른쪽 마우스 클릭!



볼륨 축소를 눌러줍니다.


조금만 기다리면...



디스크를 축소할 수 있는 창이 나옵니다.



축소할 공간 입력 부분에 리눅스에서 사용할 용량을 GB가 아닌 MB단위로 입력해주세요. (저는 200GB로 했으므로 204800MB!)


할당이 완료되었습니다!



2. 리눅스를 설치하자!


리눅스 설치 디스크로 부팅해줍니다.





설치 형식에서 기타를 누른 후 계속을 눌러줍니다.



아까 할당한 드라이브를 눌러줍니다. (남은 공간이라고 표시됩니다.)

만약 잘못하실 경우 엉뚱한 드라이브가 날라가는 신기한 현상이...ㅎ



더블클릭 후 파티션을 아래 사진과 같이 하신 후 확인을 눌러줍니다.

(스왑 영역은 Windows의 가상 메모리와 비슷한 개념이라고 보시면 됩니다.)





스왑 영역이 할당되었습니다.


다시 남은 공간(아까 할당한 드라이브)을 더블클릭



아래 사진 처럼 해주신 후 확인을 눌러주세요.

(이 ext4 저널링 파일 시스템으로 맞춘 드라이브에 리눅스가 설치됩니다.)




부트로더를 설치할 장치에는 딱히 손은 안대셔도 됩니다.


이제 설치해주시면 됩니다!


부트로더를 설치할 장치는 리눅스에서는 GRUB라는 부트로더가 있는데 이 친구가 있어야 윈도우와 리눅스를 멀티부팅 할 수 있습니다.


저 같은 경우 SSD와 HDD가 있는데, SSD에는 Windows를 설치했고, HDD에는 저의 소중한 데이터(??)들과 리눅스가 설치되어 있습니다.

부트로더를 HDD에 설치했기 때문에 BIOS 설정에서 부팅 순위를 HDD로 1순위로 해주어야 멀티 부팅 메뉴가 나옵니다.


이상 포스팅을 마칩니다!

 

Posted by uniqueone
,
http://kcsdbma.tistory.com/10

 

 

 

Posted by uniqueone
,
http://doubuntu.tistory.com/2

 

 

제 1 장 우분투 설치[14.04LTS]-DoUbuntu Install

** 보다 많은 스크린샷을 보여줌으로 따라하기쉽게 끔 노력하겠습니다.

** 내용이 좋다고 생각되시면 펌보다는 링크(홍보)를 걸어주세요^^

** 댓글에는 인사대신 적용 안되는 부분과 상황을 기재 바랍니다.(오류내용 올려주시면 수정하겠습니다.)

** 참고로 다음카페/네이버카페/네이버블로그에 '우분투하자' '우분투백서' 등을 통폐합하여 여기로 이전합니다.


자 시작합니다. Do~Ubuntu


1. 우분투 설치  준비(Are U Ready?)
 

- 준비물 :  컴퓨터 (우분투라고 해서 무조건 안쓰거나 낮은 사양의 컴퓨터는 사절이다)

                           (필자의 컴퓨터4대는 사양이 CPU-APU/I3/I5  RAM-4G/8G/16G  SSD-128/256/256 입니다.)

      USB 메모리 2G 이상 (공CD 로는 구울수없는 용량이며 공DVD 가능)

      기본지식 : 이 글만 잘따라하면 될듯 합니다.(필요하다면 다른사이트도 참조하세요)      

      마음가짐 : 포기하지 않고 우분투를 써 보겠다 하자하자! 

// 우분투 부팅 이미지파일 다운로드 위치 : http://www.ubuntu.com/download/desktop

// 웹사이트 주소에 들어가면 아래처럼 영어로 된페이지가 뜬다 당황하지말고 가볍게 [ 다운로드 ] 클릭한다

// 다운로드를 클릭하면 다운로드 전에 기부하라는 화면이 뜬다 마우스로 드래그하면 "0"이 된다 모두 "0"을 만들고

// 하단에 다운로드하면 된다! (필자의 경우 말 기부하고 싶었다)

** [ 다운로드 ] 하고 저장 누르면 저장위치가 뜨고 확인하면 받아진다.

** 시간이 조금 걸린다. 커피한잔합시다.


2. 우분투 부팅파일 만들기-USB (Do it!)

설치파일을 다 받았으면 이제 부팅USB 를 만들어야 한다.(모든운영체가 비슷하다 태생이 다른애들은 제외.)

설치 파일이 981MB 이기 때문에 CD로 굽지는 못하지만, DVD로 굽거나, USB 메모리를 이용하면된다.

- DVD : ISO 이미지 굽는법은 따로 설명하지 않겠습니다. (검색창에 ISO 굽기 검색하면 쭉 나옴)

- USB :  우분투 USB를 만들기 위해서는 'Universal-USB-Installer' 라는 프로그램이 필요합니다

          ** 파일은 아래 첨부 (1.9.5.5)    ** 자료실에도 올리겠습니다.

          ** USB메모리는 2기가 이상으로 준비해주세요 

 

- 부팅 USB만들기 : 여기보면 알수 있습니다.

http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-windows

위 사이트는 영어로 돼있으니 간략하게 정리하면 이렇다

1. 다운로드 받은 파일(Universal-USB-Installer-1.9.5.5.exe)을 클릭 실행한다.

Universal-USB-Installer-1.9.5.5.exe


2. 
아래와 같이 소스에서 우분투(ubuntu)를 선택한다. 

 ** 이 파일은 우분투 이외에도 윈도우나 다른 리눅스도 사용할 수 있다


3. 다운은 이전에 받은 우분투 이미지파일 을 선택한다.

4. 다음은 USB 선택 - 선택 란 옆에 포맷(Format) 체크 필수

5. 만들기( Create )클릭 후 기다리면 끝

** 아직 스크린샷이 준비가 부족해서 조금 어려울 수도 있다

** 잘 모르시는 분은 http://deviantcj.tistory.com/465 - 여기에서 자세한 설명도 참조하세요.


3. 우분투 설치하기(Right Now)

1. 컴퓨터 부팅설정을 변경하는 C-MOS 셋팅(설치에 필요한 필수사항)

** 모든 스크린샷은 가상화면에서 이쁘게 찍었으나 사진자료를 전부 분실(ㅜㅜ)해서 휴대폰이미지로 대체합니다.

** http://www.ubuntu.com/download/desktop/install-ubuntu-desktop 영문설명사이트

** 컴퓨터 마다 다르겠지만 보통 F1 키 / F2 키 / F10 키 / Del(ete) 키 이넷중 하나인데

** 브랜드별로 보면 삼성(F1/Del) Asus(F2/Del) HP(F10) LG(F2/Del)정도로 볼수 있다.

** 물론 보이는 방식도 위의 화면과 같지않다. 어디에나 잘 보다보면 부팅(Boot)가 있다 찾아보자


2. 부트(Boot) 메뉴에서 하드셋팅 관련메뉴로 갑니다.

//

** 위 화면도 제조사별로 다르다 최근 ASUS나 기가바이트같은 회사는 그래픽(GUI)이 많아졌다.


// 아래와 같이 USB부팅을 선택합니다.

// 순서변경 방법은 화면 오른쪽에 있습니다.(보통 '+' '-' 이거나 방향키 상하인경우도 있습니다.)


// 설정이 USB로 되있는지 확인합니다.(설치후에는 다시 원래대로 하드로 선택합니다.)


//셋팅이 끝났으면 저장하고 재부팅 합니다.


3. 정상적으로 USB부트(Boot) 셋팅되었다면 아래와 같이 설치 시작화면이 뜹니다.


4. 설치 시작화면

** 설치 시작 처음화면입니다.(기본이 영어네요 한글로 바꿉시다)

** 아래와 같이 환영메세지와 언어선택화면이 나옵니다.스크롤을 이용해서 내려보면 아래와같이 한글이 나온다.

// 한글을 선택하고 [Ubuntu 설치]를 눌러서 설치 시작합니다.



5. 기본정보 확인과 기본셋팅입니다.

// 위 그림과 같이 [설치 중 업데이트 다운로드] 는 체크하지 않습니다.(시간도 많이 걸리고 나중에 하는게 편함)

// [서드파티 소프트웨어 설치] 는 해도 되고 안해도 됩니다.

// 체크 됬으면 [계속] 을 눌러 다음으로 진행합니다.


6. 파티션 설정에 관련하여 새로 설치하거나 덮어쓰거나 사용자 정의할수 있습니다.

// 위와 같이 [기타] 를 선택하고 [계속] 을 클릭합니다.

** 필자의 경우 윈도우들과 듀얼부팅을 사용하기에 필수로 기타를 선택했습니다.

** 모두 지우고 다시 설치 시  하드가 파티션없이 설치 될수 있으니 기타를 선택해주시면 좋겠습니다.


7. 파티션 설정 화면입니다.*(윈도우가 설치되어있다면 윈도우 파티션은 건드리지 마세요)

** 남은공간이 보입니다. 여기에 분활하든 통으로 잡으시던 합니다.

// 남은공간 선택하시고 아래에 [+] 를 눌러주세요

** 위와 같이 파티션 만들기 화면이 나옵니다.

// [ 크기 ] : 파티션 크기를 설정합니다.

** 파티션크기는 필자의 경우 전부를 잡았습니다. 30~50기가 정도로 잡으면 전체적을 쓰는데 지장이 없기 때문입니다.

** 필요에 따라 크기를 적습니다. 참고로 1000MB 가 1GB 정도로 보시면 됩니다.(물런 1024K 가 1M 입니다)

** 메모리가 적어서 SWAP공간(하드디스크의 가상메모리)이 필요하면 적당량 빼줍니다.(메모리 많으면 통)

// [ 새 파티션의 종류] : 주 파티션을 선택합니다.

// [ 용도 ] : 스크린샷은 없으나 포맷방식이 나오는데 EXT4 최신을 선택합니다.

// [ 마운트위치 ] : 음~설치 위치정도인데 루트로 보시면 됩니다. ' / ' <<선택합니다.


// 셋팅 완료 후에 [ 지금 설치 ] 를 클릭하면 다음 화면이 나옵니다.

// 필자의 경우 메모리가 8기가 이상이라서 SWAP을 무시 해서 저런메세지가 나왔습니다. 무시합니다. [ 계속 ]클릭


8. 국가(지역) 선택화면(시간과 날짜 설정을 위함입니다. 나중에 설정변경 가능)

// 서울 선택하고 [ 계속] 클릭


8. 키보드 선택 및 배치화면

// 위 화면 처럼 하단에 [ 한국어 ] [ 한국어 ] 선택하고 [ 계속 ] 클릭합니다.


8. 설치 파일 복사 화면 시작.(끝날 때 까지 가만히 둡니다.시간이 조금 걸림)

** 오른쪽에 SKIP 누르면 안됩니다!!

** 드디여 설치의 끝이 보이네요


8. 파일 복사완료 화면

// 완료완료 창이 뜨면 [ 지금 다시 시작] 클릭합니다.

** 자 이제 부터 맘에 준비 재부팅후 바로 C-MOS 셋팅으로 들어가야 합니다.(위에서 했던거 기억나시죠?;;)


9. 재부팅후 바로 씨모스 셋팅화면으로 들어옵니다.

// 다시 정상적으로 하드부팅으로 바꾸기 위해서 위와같이 다시 하드를 상단으로 옴겨서 셋합니다.

** 다시 돌려놓지 않으면 평생 USB로 부팅해서 설치만 합니다.ㅎㅎ


10. 재부팅후 멀티 부팅이라면 아래와 같이 부트메뉴가 나옵니다.(우분트만 있다면 뜨지 않습니다.)

 

11. 처음 부팅후 첫 화면입니다.

** 자 이제 설치는 끝이 났습니다.

** 다음 포스팅에서는 실사용을 위한 셋팅(준비작업)을 해보겠습니다.

** 사용자 설정/메뉴/방법 등등


** 운영체제 포스팅 하려니 너무 시간이 오래 걸렸네요. 긴글 읽느라 수고하셧구요 다음시간에 뵙겠습니다.

** 아래 넘들을 제가 포스팅중에 아는동생과 함께 처리 했습니다.

** 첫포스팅이 끝났읍니다. 다음포스팅에 뵙겠습니다.

** 참고로 아래는 메뉴 이름 입니다. 익혀두세요.


 

Posted by uniqueone
,
http://matlab.izmiran.ru/help/techdoc/matlab_external/ch04cre7.html

 

 

External Interfaces Previous page   Next Page

Passing Two or More Inputs or Outputs

The plhs[] and prhs[] parameters are vectors that contain pointers to each left-hand side (output) variable and each right-hand side (input) variable, respectively. Accordingly, plhs[0]contains a pointer to the first left-hand side argument, plhs[1] contains a pointer to the second left-hand side argument, and so on. Likewise, prhs[0] contains a pointer to the first right-hand side argument, prhs[1] points to the second, and so on.

This example, xtimesy, multiplies an input scalar by an input scalar or matrix and outputs a matrix. For example, using xtimesy with two scalars gives

  • x = 7;
    y = 7;
    z = xtimesy(x,y)
    
    z = 
         49
    

Using xtimesy with a scalar and a matrix gives

  • x = 9;
    y = ones(3);
    z = xtimesy(x,y)
    
    z = 
         9      9      9
         9      9      9
         9      9      9
    

This is the corresponding MEX-file C code.

  • /*
     * =============================================================
     * xtimesy.c - example found in API guide
     *
     * Multiplies an input scalar times an input matrix and outputs a
     * matrix. 
     *
     * This is a MEX-file for MATLAB.
     * Copyright (c) 1984-2000 The MathWorks, Inc.
     * =============================================================
     */
    
    /* $Revision: 1.10 $ */
    
    #include "mex.h"
    
    void xtimesy(double x, double *y, double *z, int m, int n)
    {
      int i,j,count = 0;
      
      for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
          *(z+count) = x * *(y+count);
          count++;
        }
      }
    }
    
    
    /* The gateway routine */
    void mexFunction(int nlhs, mxArray *plhs[],
                     int nrhs, const mxArray *prhs[])
    {
      double *y, *z;
      double x;
      int status,mrows,ncols;
      
      /*  Check for proper number of arguments. */
      /* NOTE: You do not need an else statement when using
         mexErrMsgTxt within an if statement. It will never
         get to the else statement if mexErrMsgTxt is executed.
         (mexErrMsgTxt breaks you out of the MEX-file.) 
      */
      if (nrhs != 2) 
        mexErrMsgTxt("Two inputs required.");
      if (nlhs != 1) 
        mexErrMsgTxt("One output required.");
      
      /* Check to make sure the first input argument is a scalar. */
      if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) ||
          mxGetN(prhs[0])*mxGetM(prhs[0]) != 1) {
        mexErrMsgTxt("Input x must be a scalar.");
      }
      
      /* Get the scalar input x. */
      x = mxGetScalar(prhs[0]);
      
      /* Create a pointer to the input matrix y. */
      y = mxGetPr(prhs[1]);
      
      /* Get the dimensions of the matrix input y. */
      mrows = mxGetM(prhs[1]);
      ncols = mxGetN(prhs[1]);
      
      /* Set the output pointer to the output matrix. */
      plhs[0] = mxCreateDoubleMatrix(mrows,ncols, mxREAL);
      
      /* Create a C pointer to a copy of the output matrix. */
      z = mxGetPr(plhs[0]);
      
      /* Call the C subroutine. */
      xtimesy(x,y,z,mrows,ncols);
    }
    

As this example shows, creating MEX-file gateways that handle multiple inputs and outputs is straightforward. All you need to do is keep track of which indices of the vectors prhs andplhs correspond to the input and output arguments of your function. In the example above, the input variable x corresponds to prhs[0] and the input variable y to prhs[1].

Note that mxGetScalar returns the value of x rather than a pointer to x. This is just an alternative way of handling scalars. You could treat x as a 1-by-1 matrix and use mxGetPr to return a pointer to x.


 

Previous page   Passing Strings   Passing Structures and Cell Arrays  Next page

© 1994-2005 The MathWorks, Inc.


 

Posted by uniqueone
,

https://github.com/YuvalNirkin/find_face_landmarks/blob/master/sequence_face_landmarks/CMakeLists.txt

http://gyeongju.tistory.com/entry/DLIB-C-Library

http://stackoverflow.com/questions/32736149/how-to-load-jpeg-file-using-dlib-libarary


http://stackoverflow.com/questions/24173330/cmake-is-not-able-to-find-boost-libraries

http://stackoverflow.com/questions/13280823/cmake-not-finding-boost

https://github.com/YuvalNirkin/find_face_landmarks/issues/2

https://github.com/YuvalNirkin/motionseg/blob/master/cmake/Finddlib.cmake

https://github.com/dorian3d/DBoW2/pull/3/files

https://github.com/dorian3d/DLib

http://stackoverflow.com/questions/33996361/create-a-shared-library-for-dlib


http://fossies.org/diffs/dlib/18.17_vs_18.18/dlib/CMakeLists.txt-diff.html

http://dlib.net/dlib/CMakeLists.txt.html

https://github.com/dorian3d/DBoW2

https://github.com/dorian3d/DBoW2/blob/master/CMakeLists.txt

https://github.com/YuvalNirkin/motionseg/blob/master/cmake/Finddlib.cmake


https://sourceforge.net/p/dclib/discussion/442518/thread/b441f3a3/

 

 

 

 

 

 

 

 

Posted by uniqueone
,

http://www.paulvangent.com/2016/08/05/emotion-recognition-using-facial-landmarks/

 

 

 

Emotion Recognition using Facial Landmarks, Python, DLib and OpenCV

Banner

Let’s improve on the emotion recognition from a previous article about FisherFace Classifiers. We will be using facial landmarks and a machine learning algorithm, and see how well we can predict emotions in different individuals, rather than on a single individual like in another article about theemotion recognising music player.


Important: The code in this tutorial is licensed under the GNU 3.0 open source license and you are free to modify and redistribute the code, given that you give others you share the code with the same right, and cite my name (use citation format below). You are not free to redistribute or modify the tutorial itself in any way. By reading on you agree to these terms. If you disagree, please navigate away from this page.

Citation format
van Gent, P. (2016). Emotion Recognition Using Facial Landmarks, Python, DLib and OpenCV. A tech blog about fun things with Python and embedded electronics. Retrieved from: http://www.paulvangent.com/2016/08/05/emotion-recognition-using-facial-landmarks/

IE users: I’ve gotten several reports that sometimes the code blocks don’t display correctly or at all on Internet Explorer. Please refresh the page and they should display fine.


Introduction and getting started
Using Facial Landmarks is another approach to detecting emotions, more robust and powerful than the earlier used fisherface classifier, but also requiring some more code and modules. Nothing insurmountable though. We need to do a few things:

  • Get images from a webcam
  • Detect Facial Landmarks
  • Train a machine learning algorithm (we will use a linear SVM)
  • Predict emotions

Those who followed the two previous posts about emotion recognition will know that the first step is already done.

Also we will be using:

  • Python (2.7 or higher is fine, anaconda + jupyter notebook is a nice combo-package)
  • OpenCV (I still use 2.4.9……so lazy, grab here)
  • SKLearn (if you installed anaconda, it is already there, otherwise get it with pip install sklearn)
  • Dlib (a C++ library for extracting the facial landmarks, see below for instructions)
  • Visual Studio 2015 (get the community edition here, also select the Python Tools in the installation dialog).
    • Note that VS is not strictly required, I just build the modules against it. However it is a very nice IDE that also has good Python bindings and allows you to quickly make GUI applications to wrap around your Python scripts. I would recommend you give it a go

Installing and building the required libraries

I am on Windows, and building libraries on Windows always gives many people a bad taste in their mouths. I can understand why, however it’s not all bad and often the problems people run into are either solved by correctly setting PATH variables, providing the right compiler or reading the error messages and installing the right dependencies. I will walk you through the process of compiling and installing Dlib.

First install CMake. This should be straightforward, download the windows installer and install. Make sure to select the option “Add CMake to the system PATH” during the install. Choose whether you want this for all users or just for your account.

Download Boost-Python and extract the package. I extracted it into C:\boost but it can be anything. Fire up a command prompt and navigate to the directory. Then do:

1
2
3
4
5
6
7
bootstrap.bat #First run the bootstrap.bat file supplied with boost-python
#Once it finished invoke the install process of boost-python like this:
b2 install #This can take a while, go get a coffee
#Once this finishes, build the python modules like this
b2 -a --with-python address-model=64 toolset=mscv runtime-link=static #Again, this takes a while, reward yourself and get another coffee.

Once all is done you will find a folder named bin, or bin.v2, or something like this in your boost folder. Now it’s time to build Dlib.

Download Dlib and extract it somewhere. I used C:\Dlib but you can do it anywhere. Go back to your command prompt, or open a new one if you closed it, and navigate to your Dlib folder. Do this sequentially:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Set two flags so that the CMake compiler knows where to find the boost-python libraries 
set BOOST_ROOT=C:\boost #Make sure to set this to the path you extracted boost-python to!
set BOOST_LIBRARYDIR=C:\boost\stage\lib #Same as above
# Create and navigate into a directory to build into
mkdir build
cd build
# Build the dlib tools
cmake ..
#Navigate up one level and run the python setup program
cd ..
python setup.py install #This takes some time as well. GO GET ANOTHER COFFEE TIGER!

Open your Python interpreter and type import dlib”. If you receive no messages, you’re good to go! Nice.

 


Testing the landmark detector
Before diving into much of the coding (which probably won’t be much because we’ll be recycling), let’s test the DLib installation on your webcam. For this you can use the following snippet. If you want to learn how this works, be sure to also compare it with the first script under “Detecting your face on the webcam” in the previous post. Much of the same OpenCV code to talk to your webcam, process the image by converting to grayscale, optimising the contrast with an adaptive histogram equalisation and displaying it is something we did there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#Import required modules
import cv2
import dlib
#Set up some required objects
video_capture = cv2.VideoCapture(0) #Webcam object
detector = dlib.get_frontal_face_detector() #Face detector
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") #Landmark identifier. Set the filename to whatever you named the downloaded file
while True:
    retframe = video_capture.read()
    gray = cv2.cvtColor(framecv2.COLOR_BGR2GRAY)
    clahe = cv2.createCLAHE(clipLimit=2.0tileGridSize=(8,8))
    clahe_image = clahe.apply(gray)
    detections = detector(clahe_image1) #Detect the faces in the image
    for k,d in enumerate(detections)#For each detected face
        
        shape = predictor(clahe_imaged) #Get coordinates
            for i in range(1,68)#There are 68 landmark points on each face
                cv2.circle(frame(shape.part(i).xshape.part(i).y)1(0,0,255)thickness=2) #For each point, draw a red circle with thickness2 on the original frame
    cv2.imshow("image"frame) #Display the frame
    if cv2.waitKey(1) & 0xFF == ord('q')#Exit program when the user presses 'q'
        break

This will result in your face with a lot of dots outlining the shape and all the “moveable parts”. The latter is of course important because it is what makes emotional expressions possible.

Unknown-3 Unknown-2

Unknown

 

Note if you have no webcam and/or would rather like to try this on a static image, replace line #11 with something like frame = cv2.imread(“filename”) and comment out line #6 where we define the video_capture object. You will get something like:

33

 

my face has dots
people tell me my face has nice dots
experts tell me these are the best dots
I bet I have the best dots

 

 

 


Extracting features from the faces
The first thing to do is find ways to transform these nice dots overlaid on your face into features to feed the classifer. Features are little bits of information that describe the object or object state that we are trying to divide into categories. Is this description a bit abstract? Imagine you are in a room without windows with only a speaker and a microphone. I am outside this room and I need to make you guess whether there is a cat, dog or a horse in front of me. The rule is that I can only use visual characteristics of the animal, no names or comparisons. What do I tell you? Probably if the animal is big or small, that it has fur, that the fur is long or short, that it has claws or hooves, whether it has a tail made of flesh or just from hair, etcetera. Each bit of information I pass you can be considered afeature, and based the same feature set for each animal, you would be pretty accurate if I chose the features well.

How you extract features from your source data is actually where a lot of research is, it’s not just about creating better classifying algorithms but also about finding better ways to collect and describe data. The same classifying algorithm might function tremendously well or not at all depending on how well the information we feed it is able to discriminate between different objects or object states. If, for example, we would extract eye colour and number of freckles on each face, feed it to the classifier, and then expect it to be able to predict what emotion is expressed, we would not get far. However, the facial landmarks from the same image material describe the position of all the “moving parts” of the depicted face, the things you use to express an emotion. This is certainly useful information!

To get started, let’s take the code from the example above and change it so that it fits our current needs, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import cv2
import dlib
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
def get_landmarks(image):
    detections = detector(image1)
    for k,d in enumerate(detections)#For all detected face instances individually
        shape = predictor(imaged) #Draw Facial Landmarks with the predictor class
        xlist = []
        ylist = []
        for i in range(1,68)#Store X and Y coordinates in two lists
            xlist.append(float(shape.part(i).x))
            ylist.append(float(shape.part(i).y))
            
        for xy in zip(xlistylist)#Store all landmarks in one list in the format x1,y1,x2,y2,etc.
            landmarks.append(x)
            landmarks.append(y)
    if len(detections) > 0:
        return landmarks
    else#If no faces are detected, return error message to other function to handle
        landmarks = "error"
        return landmarks

Here we extract the coordinates of all face landmarks. These coordinates are the first collection of features, and this might be the end of the road. You might also continue and try to derive other measures from this that will tell the classifier more about what is happening on the face. Whether this is necessary or not depends. For now let’s assume it is necessary, and look at ways to extract more information from what we have. Feature generation is always a good thing to try, if only because it brings you closer to the data and might give you ideas or alternative views at it because you’re getting your hands dirty. Later on we’ll see if it was really necessary at a classification level.

To start, look at the coordinates. They may change as my face moves to different parts of the frame. I could be expressing the same emotion in the top left of an image as in the bottom right of another image, but the resulting coordinate matrix would express different numerical ranges. However, the relationships between the coordinates will be similar in both matrices so some information is present in a location invariant form, meaning it is the same no matter where in the picture my face is.

Maybe the most straightforward way to remove numerical differences originating from faces in different places of the image would be normalising the coordinates between 0 and 1. This is easily done by: Norm_Formula, or to put it in code:

1
2
xnorm = [(i-min(xlist))/(max(xlist)-min(xlist)) for i in xlist]
ynorm = [(i-min(ylist))/(max(ylist)-min(ylist)) for i in ylist]

However, there is a problem with this approach because it fits the entire face in a square with both axes ranging from 0 to 1. Imagine one face with its eyebrows up high and mouth open, the person could be surprised. Now imagine an angry face with eyebrows down and mouth closed. If we normalise the landmark points on both faces from 0-1 and put them next to each other we might see two very similar faces. Because both distinguishing features lie at the edges of the face, normalising will push both back into a very similar shape. The faces will end up looking very similar. Take a moment to appreciate what we have done; we have thrown away most of the variation that in the first place would have allowed us to tell the two emotions from each other! Probably this will not work. Of course some variation remains from the open mouth, but it would be better not to throw so much away.

A less destructive way could be to calculate the position of all points relative to each other. To do this we calculate the mean of both axes, which results in the point coordinates of the sort-of “centre of gravity” of all face landmarks. We can then get the position of all points relative to this central point. Let me show you what I mean. Here’s my face with landmarks overlaid:

face2

First we add a “centre of gravity”, shown as a blue dot on the image below:

face3

Lastly we draw a line between the centre point and each other facial landmark location:

face4

Note that each line has both a magnitude (distance between both points) and a direction (angle relative to image where horizontal=0°), in other words, a vector.

But, you may ask, why don’t we take for example the tip of the nose as the central point? This would work as well, but would also throw extra variance in the mix due to short, long, high- or low-tipped noses. The “centre point method” also introduces extra variance; the centre of gravity shifts when the head turns away from the camera, but I think this is less than when using the nose-tip method because most faces more or less face the camera in our sets. There are techniques to estimate head pose and then correct for it, but that is beyond this article.

There is one last thing to note. Faces may be tilted, which might confuse the classifier. We can correct for this rotation by assuming that the bridge of the nose in most people is more or less straight, and offset all calculated angles by the angle of the nose bridge. This rotates the entire vector array so that tilted faces become similar to non-tilted faces with the same expression. Below are two images, the left one illustrates what happens in the code when the angles are calculated, the right one shows how we can calculate the face offset correction by taking the tip of the nose and finding the angle the nose makes relative to the image, and thus find the angular offset β we need to apply.

anglecalc

Now let’s look at how to implement what I described above in Python. It’s actually fairly straightforward. We just slightly modify the get_landmarks() function from above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
def get_landmarks(image):
    detections = detector(image1)
    for k,d in enumerate(detections)#For all detected face instances individually
        shape = predictor(imaged) #Draw Facial Landmarks with the predictor class
        xlist = []
        ylist = []
        for i in range(1,68)#Store X and Y coordinates in two lists
            xlist.append(float(shape.part(i).x))
            ylist.append(float(shape.part(i).y))
            
        xmean = np.mean(xlist) #Find both coordinates of centre of gravity
        ymean = np.mean(ylist)
        xcentral = [(x-xmean) for x in xlist] #Calculate distance centre <-> other points in both axes
        ycentral = [(y-ymean) for y in ylist]
        
        if xlist[26] == xlist[29]#If x-coordinates of the set are the same, the angle is 0, catch to prevent 'divide by 0' error in function
            anglenose = 0
        else:
            anglenose = int(math.atan((ylist[26]-ylist[29])/(xlist[26]-xlist[29]))*180/math.pi) #point 29 is the tip of the nose, point 26 is the top of the nose brigde
        if anglenose < 0#Get offset by finding how the nose brigde should be rotated to become perpendicular to the horizontal plane
            anglenose += 90
        else:
            anglenose -= 90
        landmarks_vectorised = []
        for xywz in zip(xcentralycentralxlistylist):
            landmarks_vectorised.append(x) #Add the coordinates relative to the centre of gravity
            landmarks_vectorised.append(y)
            #Get the euclidean distance between each point and the centre point (the vector length)
            meannp = np.asarray((ymean,xmean))
            coornp = np.asarray((z,w))
            dist = np.linalg.norm(coornp-meannp)
            landmarks_vectorised.append(dist)
            #Get the angle the vector describes relative to the image, corrected for the offset that the nosebrigde has when the face is not perfectly horizontal
            anglerelative = (math.atan((z-ymean)/(w-xmean))*180/math.pi) - anglenose
            landmarks_vectorised.append(anglerelative)
            
    if len(detections) < 1
        landmarks_vestorised = "error" #If no face is detected set the data to value "error" to catch detection errors
    
    return landmarks_vectorised
    

That was actually quite manageable, no? Now it’s time to put all of the above together with some stuff from the first post. The goal is to read the existing dataset into a training and prediction set with corresponding labels, train the classifier (we use Support Vector Machines with linear kernel from SKLearn, but feel free to experiment with other available kernels such as polynomial or rbf, or other classifiers!), and evaluate the result. This evaluation will be done in two steps; first we get an overall accuracy after ten different data segmentation, training and prediction runs, second we will evaluate the predictive probabilities.

 


Déja-Vu All Over Again

The next thing we will be doing is returning to the two datasets from the original post. Let’s see how this approach stacks up.

First let’s write some code. The approach is to first extract facial landmark points from the images, randomly divide 80% of the data into a training set and 20% into a test set, then feed these into the classifier and train it on the training set. Finally we evaluate the resulting model by predicting what is in the test set to see how the model handles the unknown data. Basically a lot of the steps are the same as what we did earlier.

The quick and dirty (I will clean and ‘pythonify’ the code later, when there is time) solution based off of earlier code could be something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import cv2globrandommathnumpy as npdlibitertools
from sklearn.svm import SVC
__author__ = "Paul van Gent, 2016" #Please leave this line in
emotions = ["anger""contempt""disgust""fear""happiness""neutral""sadness""surprise"] #Emotion list
clahe = cv2.createCLAHE(clipLimit=2.0tileGridSize=(8,8))
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") #Or set this to whatever you named the downloaded file
clf = SVC(kernel='linear'probability=Truetol=1e-3)#, verbose = True) #Set the classifier as a support vector machines with polynomial kernel
def get_files(emotion)#Define function to get file list, randomly shuffle it and split 80/20
    files = glob.glob("dataset\\%s\\*" %emotion)
    random.shuffle(files)
    training = files[:int(len(files)*0.9)] #get first 80% of file list
    prediction = files[-int(len(files)*0.1):] #get last 20% of file list
    return trainingprediction
def get_landmarks(image):
    detections = detector(image1)
    for k,d in enumerate(detections)#For all detected face instances individually
        shape = predictor(imaged) #Draw Facial Landmarks with the predictor class
        xlist = []
        ylist = []
        for i in range(1,68)#Store X and Y coordinates in two lists
            xlist.append(float(shape.part(i).x))
            ylist.append(float(shape.part(i).y))
            
        xmean = np.mean(xlist) #Get the mean of both axes to determine centre of gravity
        ymean = np.mean(ylist)
        xcentral = [(x-xmean) for x in xlist] #get distance between each point and the central point in both axes
        ycentral = [(y-ymean) for y in ylist]
        if xlist[26] == xlist[29]#If x-coordinates of the set are the same, the angle is 0, catch to prevent 'divide by 0' error in function
            anglenose = 0
        else:
            anglenose = int(math.atan((ylist[26]-ylist[29])/(xlist[26]-xlist[29]))*180/math.pi)
        if anglenose < 0:
            anglenose += 90
        else:
            anglenose -= 90
        landmarks_vectorised = []
        for xywz in zip(xcentralycentralxlistylist):
            landmarks_vectorised.append(x)
            landmarks_vectorised.append(y)
            meannp = np.asarray((ymean,xmean))
            coornp = np.asarray((z,w))
            dist = np.linalg.norm(coornp-meannp)
            anglerelative = (math.atan((z-ymean)/(w-xmean))*180/math.pi) - anglenose
            landmarks_vectorised.append(dist)
            landmarks_vectorised.append(anglerelative)
    if len(detections) < 1
        landmarks_vectorised = "error"
    return landmarks_vectorised
def make_sets():
    training_data = []
    training_labels = []
    prediction_data = []
    prediction_labels = []
    for emotion in emotions:
        trainingprediction = get_files(emotion)
        #Append data to training and prediction list, and generate labels 0-7
        for item in training:
            image = cv2.imread(item) #open image
            gray = cv2.cvtColor(imagecv2.COLOR_BGR2GRAY) #convert to grayscale
            clahe_image = clahe.apply(gray)
            get_landmarks(clahe_image)
            if landmarks_vectorised == "error":
                pass
            else:
                training_data.append(landmarks_vectorised) #append image array to training data list
                training_labels.append(emotions.index(emotion))
    
        for item in prediction:
            image = cv2.imread(item)
            gray = cv2.cvtColor(imagecv2.COLOR_BGR2GRAY)
            clahe_image = clahe.apply(gray)
            get_landmarks(clahe_image)
            if landmarks_vectorised == "error":
                pass
            else:
                prediction_data.append(landmarks_vectorised)
                prediction_labels.append(emotions.index(emotion))
    return training_datatraining_labelsprediction_dataprediction_labels   
accur_lin = []
for i in range(0,10):
    print("Making sets %s" %i) #Make sets by random sampling 80/20%
    training_datatraining_labelsprediction_dataprediction_labels = make_sets()
    npar_train = np.array(training_data) #Turn the training set into a numpy array for the classifier
    npar_trainlabs = np.array(training_labels)
    print("training SVM linear %s" %i) #train SVM
    clf.fit(npar_traintraining_labels)
    print("getting accuracies %s" %i) #Use score() function to get accuracy
    npar_pred = np.array(prediction_data)
    pred_lin = clf.score(npar_predprediction_labels)
    print "linear: "pred_lin
    accur_lin.append(pred_lin) #Store accuracy in a list
print("Mean value lin svm: %.3f" %np.mean(accur_lin)) #Get mean accuracy of the 10 runs

Remember that in the previous post, for the standard set at 8 categories we managed to get 69.3% accuracy with the FisherFace classifier. This approach yields 84.1% on the same data, a lot better!

We then reduced the set to 5 emotions (leaving out contempt, fear and sadness), because the 3 categories had very few images, and got 82.5% correct. This approach gives 92.6%, also much improvement.

After adding the less standardised and more difficult images from google, we got 61.6% correct when predicting 7 emotions (the contempt category remained very small so we left that out). This is now 78.2%, also quite an improvement. This remains the lowest accuracy, showing that for a more diverse dataset the problem is also more difficult. Keep in mind that the dataset I use is still quite small in machine learning terms, containing about 1000 images spread over 8 categories.

 


Looking at features
So we derived different features from the data, but weren’t sure whether this was strictly necessary. So was this necessary? It depends! It depends on if doing so adds more unique variance related to what you’re trying to predict, it depends on what classifier you use, etc.

Let’s run different feature combinations as inputs through different classifiers and see what happens. I’ve run all iterations on the same slice of data with 4 emotion categories of comparable size (so that running the same settings again yields the same predictive value).

 

Using all of the features described so far leads to:
Linear SVM: 93.9%
Polynomial SVM: 83.7%
Random Forest Classifier: 87.8%

Now using just the vector length and angle:
Linear SVM: 87.8%
Polynomial SVM: 87.8%
Random Forest Classifier: 79.6%

Now using just the raw coordinates:
Linear SVM: 91.8%
Polynomial SVM: 89.8%
Random Forest Classifier: 59.2%

Now replacing all training data with zeros:
Linear SVM: 32.7%
Polynomial SVM: 32.7%
Random Forest Classifier: 32.7%

 

Now this is interesting! First note that there isn’t much difference in the accuracy of the support vector machine classifiers when using the extra features we generate. This type of classifier already preprocesses the data quite extensively. The extra data we generate does not contain much if any extra information to this classifier, so it only marginally improves the performance of the linear kernel, and actually hurts the polynomial kernel because data with a lot of overlapping variance can also make a classification task more difficult. By the way, this is a nice 2D visualisation of what an SVC tries to achieve, complexity escalates when adding one dimension. Now remember that the SVC operates in an N-dimensional space and try to imagine what a set of hyperplanes in 4, 8, 12, 36 or more dimensions would look like. Don’t drive yourself crazy.

Random Forest Classifiers do things a lot differently. Essentially they are a forest of decision trees. Simplified, each tree is a long list of yes/no questions, and answering all questions leads to a conclusion. In the forest the correlation between each tree is kept as low as possible, which ensures every tree brings something unique to the table when explaining patterns in the data. Each tree then votes on what it thinks the answer is, and most votes win. This approach benefits extensively from the new features we generated, jumping from 59.2% to 87.8% accuracy as we combine all derived features with the raw coordinates.

So you see, the answer you likely get when you ask any scientist a direct question holds true here as well: it depends. Check your data, think twice and try a few things.

The last that may be noticed is that, when not adding any data at all and in stead presenting the classifiers with a matrix of zeros, they still perform slightly above the expected chance level of 25%. This is because the categories are not identically sized.

 


Looking at mistakes
Lastly, let’s take a look at where the model goes wrong. Often this is where you can learn a lot, for example this is where you might find that a single category just doesn’t work at all, which can lead you to look critically at the training material again.

One advantage of the SVM classifier we use is that it is probabilistic. This means that it assigns probabilities to each category it has been trained for (and you can get these probabilities if you set the ‘probability’ flag to True). So, for example, a single image might be “happy” with 85% probability, “angry” with “10% probability, etc.

To get the classifier to return these things you can use its predict_proba() function. You give this function either a single data row to predict or feed it your entire dataset. It will return a matrix where each row corresponds to one prediction, and each column represents a category. I wrote these probabilities to a table and included the source image and label. Looking at some mistakes, here are some notable things that were classified incorrectly (note there are only images from my google set, the CK+ set’s terms prohibit me from publishing images for privacy reasons):

 

google_140

anger: 0.03239878
contempt: 0.13635423
disgust: 0.0117559
fear: 0.00202098
neutral: 0.7560004
happy: 0.00382895
sadness: 0.04207027
surprise: 0.0155695

The correct answer is contempt. To be honest I would agree with the classifier, because the expression really is subtle. Note that contempt is the second most likely according to the classifier.

 

 

google_048

anger: 0.0726657
contempt: 0.24655082
disgust: 0.06427896
fear: 0.02427595
neutral: 0.20176133
happy: 0.03169822
sadness: 0.34911036
surprise: 0.00965867

The correct answer is disgust. Again I can definitely understand the mistake the classifier makes here (I might make the same mistake..). Disgust would be my second guess, but not the classifier’s. I have removed this image from the dataset because it can be ambiguous.

 

google_020

anger: 0.00304093
contempt: 0.01715202
disgust: 0.74954754
fear: 0.04916257
neutral: 0.00806644
happy: 0.13546932
sadness: 0.02680473
surprise: 0.01075646

The correct answer is obviously happy. This is a mistake that is less understandable but still the model is quite sure (~75%). There definitely is no hint of disgust in her face. Do note however, that happiness would be the classifier’s second guess. More training material might rectify this situation.

 

 

google_168

anger: 0.0372873
contempt: 0.08705531
disgust: 0.12282577
fear: 0.16857784
neutral: 0.09523397
happy: 0.26552763
sadness: 0.20521671
surprise: 0.01827547

The correct answer is sadness. Here the classifier is not sure at all (~27%)! Like in the previous image, the second guess (~20%) is the correct answer. This may very well be fixed by having more (and more diverse) training data.

 

 

google_034

anger: 0.01440529
contempt: 0.15626157
disgust: 0.01007962
fear: 0.00466321
neutral: 0.378776
happy: 0.00554828
sadness: 0.07485257
surprise: 0.35541345

The correct answer is surprise. Again a near miss (~38% vs ~36%)! Also note that this is particularly difficult because there are few baby faces in the dataset. When I said earlier that the extra google images are very challenging for a classifier, I meant it!

 

 

 

 


Upping the game – the ultimate challenge
Although the small google dataset I put together is more challenging than the lab-conditions of the CK/CK+ dataset, it is still somewhat controlled. For example I filtered out faces that were more sideways than frontal-facing, where the emotion was very mixed (happily surprised for example), and also where the emotion was so subtle that even I had trouble identifying it.

A far greater (and more realistic still) challenge is the SFEW/AFEW dataset, put together from a large collection of movie scenes. Read more about it here. The set is not publicly available but the author was generous enough to share the set with me so that I could evaluate the taken approach further.

Guess what, it fails miserably! It attained about 44.2% on the images when training on 90% and validating on 10% of the set. Although this is on par with what is mentioned in the paper, it shows there is still a long way to go before computers can recognize emotions with a high enough accuracy in real-life settings. There are also video clips included on which we will spend another post together with convolutional neural nets at a later time.

This set is particularly difficult because it contains different expressions and facial poses and rotations for similar emotions. This was the purpose of the authors; techniques by now are good enough to recognise emotions on controlled datasets with images taken in lab-like conditions, approaching upper 90% accuracy in many recent works (even our relatively simple approach reached early 90). However these sets do not represent real life settings very much, except maybe when using laptop webcams, because you always more or less face this device and sit at a comparable distance when using the laptop. This means for applications in marketing and similar fields the technology is already usable, albeit with much room for improvement still available and requiring some expertise to implement it correctly.

 


Final reflections
Before concluding I want you to take a moment, relax and sit back and think. Take for example the SFEW set with real-life examples, accurate classification of which quickly gets terribly difficult. We humans perform this recognition task remarkably well thanks to our highly complex visual system, which has zero problems with object rotation in all planes, different face sizes, different facial characteristics, extreme changes in lighting conditions or even partial occlusion of a face. Your first response might be “but that’s easy, I do it all the time!”, but it’s really, really, really not. Think for a moment about what an enormously complex problem this really is. I can show you a mouth and you would already be quite good at seeing an emotion. I can show you about 5% of a car and you could recognize it as a car easily, I can even warp and destroy the image and your brain would laugh at me and tell me “easy, that’s a car bro”. This is a task that you solve constantly and in real-time, without conscious effort, with virtually 100% accuracy and while only using the equivalent of ~20 watts for yourentire brain (not just the visual system). The average still-not-so-good-at-object-recognition CPU+GPU home computer uses 350-450 watts when computing. Then there’s supercomputers like theTaihuLight, which require about 15.300.000 watts (using in one hour what the average Dutch household uses in 5.1 years). At least at visual tasks, you still outperform these things by quite a large margin with only 0.00013% of their energy budget. Well done, brain!

Anyway, to try and tackle this problem digitally we need another approach. In another post we will look at various forms of neural nets (modeled after your brain) and how these may or may not solve the problem, and also at some other feature extraction techniques.

 


The CK+ dataset was used for validating and training of the classifier in this article, references to the set are:

  • Kanade, T., Cohn, J. F., & Tian, Y. (2000). Comprehensive database for facial expression analysis. Proceedings of the Fourth IEEE International Conference on Automatic Face and Gesture Recognition (FG’00), Grenoble, France, 46-53.
  • Lucey, P., Cohn, J. F., Kanade, T., Saragih, J., Ambadar, Z., & Matthews, I. (2010). The Extended Cohn-Kanade Dataset (CK+): A complete expression dataset for action unit and emotion-specified expression. Proceedings of the Third International Workshop on CVPR for Human Communicative Behavior Analysis (CVPR4HB 2010), San Francisco, USA, 94-101.

The SFEW/AFEW dataset used for evaluation is authored by and described in:

  • A. Dhall, R. Goecke, S. Lucey and T. Gedeon, “Collecting Large, Richly Annotated Facial- Expression Databases from Movies”, IEEE MultiMedia 19 (2012) 34-41.
  • A. Dhall, R. Goecke, J. Joshi, K. Sikka and T. Gedeon, “ Emotion Recognition In The Wild Challenge 2014: Baseline, Data and Protocol”, ACM ICMI 2014.
Posted by uniqueone
,
http://www.paulvangent.com/2016/03/30/analyzing-a-discrete-heart-rate-signal-using-python-part-3/

 

 

 

 

Analyzing a Discrete Heart Rate Signal Using Python – Part 3

 

 

 

 

Analyzing a Discrete Heart Rate Signal Using Python – Part 3

HB

This the third part in a four part series about how to use Python for heart rate analysis. In this part you will learn about how to improve peak detection using a dynamic threshold, signal filtering, and outlier detection.


Important: The code in this tutorial is licensed under the GNU 3.0 open source license and you are free to modify and redistribute the code, given that you give others you share the code with the same right, and cite my name (use citation format below). You are not free to redistribute or modify the tutorial itself in any way. By reading on you agree to these terms. If you disagree, please navigate away from this page.

Citation format
van Gent, P. (2016). Analyzing a Discrete Heart Rate Signal Using Python. A tech blog about fun things with Python and embedded electronics. Retrieved from: http://www.paulvangent.com/2016/03/30/analyzing-a-discrete-heart-rate-signal-using-python-part-3

IE users: I’ve gotten several reports that sometimes the code blocks don’t display correctly or at all on Internet Explorer. Please refresh the page and they should display fine.


The following tutorial assumes basic knowledge of the Python programming language, FIR-filters andfast fourier transform methods. The tutorial should be suitable for those with most levels of Python skill. It is divided into separate parts so that you can easily skip over those parts you understand anyway. The data was collected with a simple data logger based on an ATTiny45, as described in another post.

All data in this tutorial is recorded with the Pulse Sensor, which I’ve found to be a great little device to easily log heart rate data from the fingertips. I have used it / am using it for research with video games, driving simulators and on-road experiments with car drivers.


Some Theory and Background
So far we’ve been over how to analyze a heart rate signal and extract the most widely used time domain and frequency domain measures from it. However, the signal we used was ideal. Now consider this signal:

Pt3_NoisySignal

A challenge! This is the other extreme of the signal qualities you will run into. To be honest I cheated and generated this signal by measuring while I was attaching the sensor to my finger (between 0 and about 4000). Immediately after this the blood vessels in the finger need to adapt to being compressed by the sensor (at about 4000-5000), after which the signal becomes stable. At about 7500, 9000 and 12000 I forcefully moved the sensor over my finger to create extra noise. I was surprised at how well the sensor suppresses noise by itself, so well done guys at pulsesensor.com.

Although this signal is manually ‘destroyed’ at points, in practice it can will happen that parts of your data contain noise or artefacts. The sensor might move which creates noise, it might not be correctly attached or become detached during the measurement, the participant might sneeze, move, or any other noise inducing factor might interfere.

We will see how to deal with this in a few stages:

  • Getting started, evaluate the result of passing this signal to our algorithm from part two;
  • Careful: Sampling Frequency;
  • Filter the signal to remove unwanted frequencies (noise);
  • Improving detection accuracy with a dynamic threshold;
  • Detecting incorrectly detected / missed peaks;
  • Removing errors and reconstructing the R-R signal to be error-free.

Getting Started
First let’s see how our algorithm from part 2 handles this signal. Download the dataset here.

1
2
3
  (...) line 37in detect_peaks
    maximum = max(window)
ValueErrormax() arg is an empty sequence

Great, it doesn’t. What is happening?

Some may have noticed it before, our detect_peaks() function will break in one eventuality: when the heart rate signal goes from being smaller than the moving average, to becoming equal to it without moving above it for at least two data points in a row. The most likely case of this happening is if the signal drops to zero for a period of time. The function will then skip to the else statement and try to detect peaks in the ROI, but no ROI has been marked because the signal never rose above the moving average, so max(window) throws the error because an empty list has no maximum. This happensbecause I’m an idiot because in the loop the situation where both signals are of equal height is not accounted for, which happens to happen early on in the signal, where I’m attaching the sensor to my finger:

Pt3_DropToZero

If you didn’t notice this in the code before, don’t worry, neither did I at first. Now to update thedetect_peaks() function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def detect_peaks(dataset):
    window = []
    peaklist = []
    listpos = 0 
    for datapoint in dataset.hart:
        rollingmean = dataset.hart_rollingmean[listpos]
        if (datapoint <= rollingmean) and (len(window) <= 1)#Here is the update in (datapoint <= rollingmean)
            listpos += 1
        elif (datapoint > rollingmean):
            window.append(datapoint)
            listpos += 1
        else:
            maximum = max(window)
            beatposition = listpos - len(window) + (window.index(max(window)))
            peaklist.append(beatposition)
            window = []
            listpos += 1
    measures['peaklist'] = peaklist
    measures['ybeat'] = [dataset.hart[x] for x in peaklist]

For now also comment out line 19, we will get to this later on.

1
2
3
4
5
6
def rolmean(datasethrwfs):
    mov_avg = pd.rolling_mean(dataset.hartwindow=(hrw*fs))
    avg_hr = (np.mean(dataset.hart)) 
    mov_avg = [avg_hr if math.isnan(x) else x for x in mov_avg]
    #mov_avg = [x*1.2 for x in mov_avg]
    dataset['hart_rollingmean'] = mov_avg

And plot again, this time with peak detection:

The module is not throwing errors anymore and is detecting peaks, but it is hardly the result we’re looking for. Let’s start by looking at noise reduction to see if we can improve the signal.


Sampling Frequency
Before getting to signal filtering let’s determine the sample rate of our file. The file from the previous two parts was 100Hz, what about this one? In practice the actual recording frequency may vary with different devices or systems. It can also be (slightly) different than what the devices are rated for. The accuracy of all the calculated measures is dependent on accurately knowing the sample rate, so this is important to check. Even a difference of 100Hz and 101Hz can lead to significantly different results if you combine data from various sources. I usually log either ‘world time’ or ‘time since start of recording’ with every data line for the purpose of calculating and verifying sample rate afterwards.

With this it is straightforward to calculate the sampling rate:

1
2
3
4
5
6
7
8
9
10
#Simple way to get sample rate
sampletimer = [x for x in dataset.timer] #dataset.timer is a ms counter with start of recording at '0'
measures['fs'] = ((len(sampletimer) / sampletimer[-1])*1000) #Divide total length of dataset by last timer entry. This is in ms, so multiply by 1000 to get Hz value
#If your timer is a date time string, convert to UNIX timestamp to more easily calculate with, use something like this:
unix_time = []
for x in dataset.datetime:
    dt = datetime.datetime.strptime(Datum"%Y-%m-%d %H:%M:%S.%f")
    unix_time.append(time.mktime(dt.timetuple()) + (dt.microsecond / 1000000.0))
measures['fs'] = (len(unix_time) / (unix_time[-1] - unix_time[0]))

The sample rate of the file provided here is actually 117Hz! The measures can now be calculated automatically using the determined sample rate.

Note that this is not the whole story, apart from sample rate you should also check your data for sampling spread; are all samples spaced evenly apart, e.g. are there no ‘gaps’ or ‘skips’ in the datastream? If your data contains gaps and skips, provided they are only a few samples long at maximum, consider interpolating the missing values before processing. If your sampling rate varies much over time you’re in trouble, use a different datalogging device.

Now that we know the sampling frequency more accurately, we can move on to signal filtering.


Signal Filtering
The first thing you should do when encountering artefacts or noisy signals (some would argue: always) is try to filter your signal. Why? Because in any real-life measuring situation your signal, whatever it may be, will consist of a signal part and an error part. This is because the perfect sensor does not exist, so it will always pick up interference from sources other than the one you are trying to measure. An example of common interference is power line noise. The AC power from the wall contacts in most countries has a frequency of 50Hz (some, such as the U.S., use 60Hz). This noise is present in many raw ECG-measurements as well.

An often used filter to reduce noise is the Butterworth Filter, which is characterized by a very even response to frequencies within the specified range. It acts as a ‘frequency gate’; suppressing frequencies beyond the specified cutoff range, more so as the frequencies move further away from it. This cutoff point is not a hard line. What I mean is that if you set the cutoff frequency at for example 5Hz, a signal of 5.1Hz will still be let through the filter, it will just be slightly reduced in amplitude (or ‘volume’, if that makes more sense). A signal of 10Hz on the other hand will only get through very weakly, if at all. This is also dependent on the filter order, as is illustrated nicely here.
Still difficult to understand? Think about it like this: you’re at a party and two people are talking to you simultaneously, leading to a situation where you cannot understand either of them. Now place a filter between you and the two others. The filter will reduce the speaking volume of person 1 without altering the volume of person 2. Now you can understand person 2 just fine. This is what the filter does except with frequencies.

Anyway, let’s get to coding and see if the signal can benefit from filtering. First download and open the dataset if you have not done it yet, define the filter using scipy.signal, filter and finally plot the signal. Assuming you’re working with the code from the previous part, define the filter and plot as such:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from scipy.signal import butterlfilter #Import the extra module required
#Define the filter
def butter_lowpass(cutofffsorder=5):
    nyq = 0.5 * fs #Nyquist frequeny is half the sampling frequency
    normal_cutoff = cutoff / nyq 
    ba = butter(ordernormal_cutoffbtype='low'analog=False)
    return ba
    
def butter_lowpass_filter(datacutofffsorder):
    ba = butter_lowpass(cutofffsorder=order)
    y = lfilter(badata)
    return y
dataset = get_data('data2.csv')
dataset = dataset[6000:12000].reset_index(drop=True) #For visibility take a subselection of the entire signal from samples 6000 - 12000 (00:01:00 - 00:02:00)
filtered = butter_lowpass_filter(dataset.hart2.5100.05)#filter the signal with a cutoff at 2.5Hz and a 5th order Butterworth filter
#Plot it
plt.subplot(211)
plt.plot(dataset.hartcolor='Blue'alpha=0.5label='Original Signal')
plt.legend(loc=4)
plt.subplot(212)
plt.plot(filteredcolor='Red'label='Filtered Signal')
plt.ylim(200,800) #limit filtered signal to have same y-axis as original (filter response starts at 0 so otherwise the plot will be scaled)
plt.legend(loc=4)
plt.show()

Now there doesn’t seem to be much improvement in this signal. If you look closely the lines are a little smoother, but there wasn’t a lot of high-amplitude, high-frequency noise there to begin with. It could even be argued that filtering slightly worsens the parts with the lower frequency noise, because there it suppresses the R-peaks a little as well. This is a good example of why you should always plot your signal when you decide to filter it. Filtering the signal changes it, and it is up to you to decide whether this change is for the better.

An example of where a Butterworth Filter was very useful, is this noisy signal I worked with in another project:

Pt3_ExFiltering

No question this improved the signal enough to process it further.


Improving Detection Accuracy With a Dynamic Threshold
The first and maybe most obvious way to reduce the incorrect labeling of the secondary peaks is to raise the moving average we use as a threshold. But raise to what level? This will be different for many different signals. We need measures to help determine which threshold level is probably the most accurate.

A few simple measures can help, we can:

  • Look at signal length and count how many peaks there are vs how many we would expect;
  • Determine and use the standard deviation of RR intervals (let’s call it RRSD).

The amount of detected peaks holds valuable information but only works to reject obvious incorrect thresholds. Depending on your application (most of mine are with people sitting still), we can reject unlikely bpm values. For example I reject thresholds resulting in average bpm of <30bpm and >130bpm. In other situations (physical excercise) the threshold can be different.

The RRSD tells us something about how spread out the differences between all RR-intervals are. Generally if there is not too much noise, the detection that has both the lowest RRSD that is not zeroand also a believable BPM value will be the best fit. RRSD must not be zero because that means there is no heart rate variability, which is a strong indication of mistakes in the detection of R-peaks.

This simple approach works because missing a beat will lead to an RR interval that is about twice as big as the average RR interval, while incorrectly labeling a beat will lead to an RR interval that is at mostabout half as big as the average RR interval, but generally smaller. Both situations lead to anincreased RRSD. In essence we exploit the fact that the heart rate signal contains a fairly stable, recurring pattern.

To illustrate let’s plot four peak detection rounds in a subselection of the dataset, with the moving average raised by 0%, 10%, 25% and 35% (top to bottom):

In the second-to-last plot all R-peaks are detected correctly and nothing has been marked as an R-peak incorrectly. Note that, although the BPM on its own could be valid for all four plots (none of them is an absolute mess), the RRSD strongly points to the plot which is most correct. I say ‘most correct’ because there are situations where some errors will remain no matter how you position the threshold, more on this later. Also note how the missing of a single peak in the last plot already causes the RRSD to increase quite a bit compared to the third one.

Now how to implement this? We cannot simply run 10.000 variations, each with a slightly more raised moving average. Apart from that this would cost us severely in overall performance of the algorithm, it would also be very redundant because many iterations would yield the same correct result (and many others the same incorrect result!). A possible solution is to check with intervals, and afterwards evaluate the most likely RRSD and BPM pair, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def detect_peaks(datasetma_percfs)#Change the function to accept a moving average percentage 'ma_perc' argument
    rolmean = [(x+((x/100)*ma_perc)) for x in dataset.hart_rollingmean] #Raise moving average with passed ma_perc
    window = []
    peaklist = []
    listpos = 0 
    for datapoint in dataset.hart:
        rollingmean = rolmean[listpos]
        if (datapoint <= rollingmean) and (len(window) <= 1)#Here is the update in (datapoint <= rollingmean)
            listpos += 1
        elif (datapoint > rollingmean):
            window.append(datapoint)
            listpos += 1
        else:
            maximum = max(window)
            beatposition = listpos - len(window) + (window.index(max(window)))
            peaklist.append(beatposition)
            window = []
            listpos += 1
    measures['peaklist'] = peaklist
    measures['ybeat'] = [dataset.hart[x] for x in peaklist]
    measures['rolmean'] = rolmean
    calc_RR(datasetfs)
    measures['rrsd'] = np.std(measures['RR_list'])
def fit_peaks(datasetfs):
    ma_perc_list = [51015202530405060708090100110120150200300] #List with moving average raise percentages, make as detailed as you like but keep an eye on speed
    rrsd = []
    valid_ma = []
    for x in ma_perc_list#Detect peaks with all percentages, append results to list 'rrsd'
        detect_peaks(datasetxfs)
        bpm = ((len(measures['peaklist'])/(len(dataset.hart)/fs))*60)
        rrsd.append([measures['rrsd']bpmx])
        
    for x,y,z in rrsd#Test list entries and select valid measures
        if ((x > 1) and ((y > 30) and (y < 130))):
            valid_ma.append([xz])
            
    measures['best'] = min(valid_makey = lambda tt[0])[1] #Save the ma_perc for plotting purposes later on (not needed)
    detect_peaks(datasetmin(valid_makey = lambda tt[0])[1]fs) #Detect peaks with 'ma_perc' that goes with lowest rrsd

Now run and plot on the dataset (timed the entire algorithm so far including loading and preprocessing at about 151ms, single core performance on an i7-4790, so it’s still still pretty quick. Multithreading will speed this up a lot):

PT3_DynPlot

That is already a lot better. It’s not dropping any correct R-peaks, but there are still a few incorrect detections remaining, and there is also the part from 0 to about 5000 which contains little to no heart rate signal. We will come back to this noisy segment and see how to detect and exclude segments of noise in part 4.

For now let’s take out the noisy part at the beginning and see how we can detect and reject outliers.


Finding Incorrectly Detected Peaks
The last thing to look at is how to detect and reject abnormal peak positions. One way to do this is to make use of the fact that the heart rate changes gradually rather than abruptly. Your bpm for example will not skip from 60bpm to 120bpm in a single beat or vice versa, so let’s make use of that.

Again this means returning to RR-intervals. Remember that if a peak is skipped in the detection, or two peaks are marked in stead of one, the resulting RR-interval will be a lot larger or smaller than the average interval. We can set a threshold and mark intervals that exceed it, similar to how we detected the peaks. For the data I collect this is enough.

There is, however, one potential complication. If you analyze a very long signal at once, wherein the heart rate changes a lot over time, this can lead to incorrect rejections. Imagine a signal with a gradually increasing heart rate, starting from 60 bpm and ending at 180bpm. This means a steady trend of decreasing RR-intervals, which is indicative of the speeding up of the heart rate rather than mistakes in the detection of R-peaks. By using just thresholds based on the mean RR-interval, this will result in a rejection of the first and last portion of the signal. If this happens in your data you could detrend RR_list first. Using scipy.signal, this is easy:

1
2
3
4
from scipy import signal
RR_list = measures['RR_list'] #First retrieve list from dictionary
RR_list_detrended = signal.detrend(RR_listtype='linear')

However, if your signal contains a period of large increases followed by similarly large decreases in heart rate, you will need to employ other methods. The solution is beyond the scope of this tutorial series, but if you have this problem you may want to use a high pass filter with a very low cutoff frequency. Another way could be to split the signal in to smaller portions (so that the increase and decrease trends are separated), detrend linearly and average the measures. If the smaller portions are not of equal length, be sure to weight the measures before averaging.
Naturally, do not calculate any measures with the detrended RR-signal, only use it for the detection of errors in peak marking.

Back to outlier rejection. For the thresholds, in practice I’ve found a threshold level of the mean of RR-differences with a band of 250-300ms on both ends works well. Using the previous code and limiting the dataset to [5000:15000] (to exclude the noisy beginning for now), implement like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
RR_list = measures['RR_list'] #Get measures
peaklist = measures['peaklist']
ybeat = measures['ybeat']
upper_threshold = (np.mean(RR_list) + 300) #Set thresholds
lower_threshold = (np.mean(RR_list) - 300)
#detect outliers
cnt = 0
removed_beats = []
removed_beats_y = []
RR2 = []
while cnt < len(RR_list):
    if (RR_list[cnt] < upper_threshold) and (RR_list[cnt] > lower_threshold):
        RR2.append(RR_list[cnt])
        cnt += 1
    else:   
        removed_beats.append(peaklist[cnt])
        removed_beats_y.append(ybeat[cnt])
        cnt += 1
measures['RR_list_cor'] = RR2 #Append corrected RR-list to dictionary
plt.subplot(211)
plt.title('Marked Uncertain Peaks')
plt.plot(dataset.hartcolor='blue'alpha=0.6label='heart rate signal')
plt.plot(measures['rolmean']color='green')
plt.scatter(measures['peaklist']measures['ybeat']color='green')
plt.scatter(removed_beatsremoved_beats_ycolor='red'label='Detection uncertain')
plt.legend(framealpha=0.6loc=4)
plt.subplot(212)
plt.title("RR-intervals with thresholds")
plt.plot(RR_list)
plt.axhline(y=upper_thresholdcolor='red')
plt.axhline(y=lower_thresholdcolor='red')
plt.show()

Resulting in:

Pt3_RR_PeakRejection4

It seems we got all the little buggers. The result is a plot with all correctly detected R-peaks marked green. The incorrect ones are marked red. The generated list measures[‘RR_list_cor’] has the RR-list without those belonging to incorrect peaks in it.

In part 4 we will look into how to mark and exclude noise segments and a few other optimizations.


Rounding up
Now tidy up all code, and also to update some functions to accept new variables and insert the peak rejection function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import math
from scipy.interpolate import interp1d
from scipy.signal import butterlfilterdetrend
measures = {}
#Preprocessing
def get_data(filename):
    dataset = pd.read_csv(filename)
    return dataset
def get_samplerate(dataset):
    sampletimer = [x for x in dataset.datetime]
    measures['fs'] = ((len(sampletimer) / sampletimer[-1])*1000)
def rolmean(datasethrwfs):
    mov_avg = pd.rolling_mean(dataset.hartwindow=(hrw*fs)center=False)
    avg_hr = (np.mean(dataset.hart)) 
    mov_avg = [avg_hr if math.isnan(x) else x for x in mov_avg]
    dataset['hart_rollingmean'] = mov_avg
def butter_lowpass(cutofffsorder=5):
    nyq = 0.5 * fs
    normal_cutoff = cutoff / nyq
    ba = butter(ordernormal_cutoffbtype='low'analog=False)
    return ba
def butter_lowpass_filter(datacutofffsorder):
    ba = butter_lowpass(cutofffsorder=order)
    y = lfilter(badata)
    return y    
def filtersignal(datacutofffsorder):
    hart = [math.pow(x3) for x in dataset.hart]
    hartfiltered = butter_lowpass_filter(hartcutofffsorder)
    dataset['hart'] = hartfiltered
#Peak detection
def detect_peaks(datasetma_percfs):
    rolmean = [(x+((x/100)*ma_perc)) for x in dataset.hart_rollingmean]
    window = []
    peaklist = []
    listpos = 0 
    for datapoint in dataset.hart:
        rollingmean = rolmean[listpos]
        if (datapoint <= rollingmean) and (len(window) <= 1)#Here is the update in (datapoint <= rollingmean)
            listpos += 1
        elif (datapoint > rollingmean):
            window.append(datapoint)
            listpos += 1
        else:
            maximum = max(window)
            beatposition = listpos - len(window) + (window.index(max(window)))
            peaklist.append(beatposition)
            window = []
            listpos += 1
    measures['peaklist'] = peaklist
    measures['ybeat'] = [dataset.hart[x] for x in peaklist]
    measures['rolmean'] = rolmean
    calc_RR(datasetfs)
    measures['rrsd'] = np.std(measures['RR_list'])
def fit_peaks(datasetfs):
    ma_perc_list = [51015202530405060708090100110120150200300] #List with moving average raise percentages, make as detailed as you like but keep an eye on speed
    rrsd = []
    valid_ma = []
    for x in ma_perc_list:
        detect_peaks(datasetxfs)
        bpm = ((len(measures['peaklist'])/(len(dataset.hart)/fs))*60)
        rrsd.append([measures['rrsd']bpmx])
    for x,y,z in rrsd:
        print xyz
        if ((x > 1) and ((y > 30) and (y < 130))):
            valid_ma.append([xz]) 
    measures['best'] = min(valid_makey = lambda tt[0])[1]
    detect_peaks(datasetmin(valid_makey = lambda tt[0])[1]fs)
def check_peaks(dataset):
    RR_list = measures['RR_list']
    peaklist = measures['peaklist']
    ybeat = measures['ybeat']
    upper_threshold = np.mean(RR_list) + 300
    lower_threshold = np.mean(RR_list) - 300
    removed_beats = []
    removed_beats_y = []
    RR_list_cor = []
    peaklist_cor = [peaklist[0]]
    cnt = 0
    while cnt < len(RR_list):
        if (RR_list[cnt] < upper_threshold) and (RR_list[cnt] > lower_threshold):
            RR_list_cor.append(RR_list[cnt])
            peaklist_cor.append(peaklist[cnt+1]) 
            cnt += 1
        else:    
            removed_beats.append(peaklist[cnt+1])
            removed_beats_y.append(ybeat[cnt+1])
            cnt += 1
    measures['RR_list_cor'] = RR_list_cor
    measures['peaklist_cor'] = peaklist_cor
#Calculating all measures
def calc_RR(datasetfs):
    peaklist = measures['peaklist']
    RR_list = []
    cnt = 0
    while (cnt < (len(peaklist)-1)):
        RR_interval = (peaklist[cnt+1] - peaklist[cnt])
        ms_dist = ((RR_interval / fs) * 1000.0)
        RR_list.append(ms_dist)
        cnt += 1
    RR_diff = []
    RR_sqdiff = []
    cnt = 0 
    while (cnt < (len(RR_list)-1))
        RR_diff.append(abs(RR_list[cnt] - RR_list[cnt+1])) 
        RR_sqdiff.append(math.pow(RR_list[cnt] - RR_list[cnt+1]2))
        cnt += 1
    measures['RR_list'] = RR_list
    measures['RR_diff'] = RR_diff
    measures['RR_sqdiff'] = RR_sqdiff
    
def calc_ts_measures(dataset):
    RR_list = measures['RR_list_cor']
    RR_diff = measures['RR_diff']
    RR_sqdiff = measures['RR_sqdiff']
    measures['bpm'] = 60000 / np.mean(RR_list)
    measures['ibi'] = np.mean(RR_list)
    measures['sdnn'] = np.std(RR_list)
    measures['sdsd'] = np.std(RR_diff)
    measures['rmssd'] = np.sqrt(np.mean(RR_sqdiff))
    NN20 = [x for x in RR_diff if (x>20)]
    NN50 = [x for x in RR_diff if (x>50)]
    measures['nn20'] = NN20
    measures['nn50'] = NN50
    measures['pnn20'] = float(len(NN20)) / float(len(RR_diff))
    measures['pnn50'] = float(len(NN50)) / float(len(RR_diff))
def calc_fd_measures(datasetfs):
    peaklist = measures['peaklist_cor']
    RR_list = measures['RR_list_cor']
    RR_x = peaklist[1:]
    RR_y = RR_list
    RR_x_new = np.linspace(RR_x[0],RR_x[-1],RR_x[-1])
    f = interp1d(RR_xRR_ykind='cubic')
    n = len(dataset.hart)
    frq = np.fft.fftfreq(len(dataset.hart)d=((1/fs)))
    frq = frq[range(n/2)]
    Y = np.fft.fft(f(RR_x_new))/n
    Y = Y[range(n/2)]
    measures['lf'] = np.trapz(abs(Y[(frq>=0.04) & (frq<=0.15)]))
    measures['hf'] = np.trapz(abs(Y[(frq>=0.16) & (frq<=0.5)]))
#Plotting it
def plotter(dataset):
    peaklist = measures['peaklist']
    ybeat = measures['ybeat']
    plt.title("Best fit: mov_avg %s percent raised" %measures['best'])
    plt.plot(dataset.hartalpha=0.5color='blue'label="heart rate signal")
    plt.plot(measures['rolmean']color ='green'label="moving average")
    plt.scatter(peaklistybeatcolor='red'label="RRSD:%.2f\nBPM:%.2f" %(np.std(measures['RR_list'])measures['bpm']))#, label="average: %.1f BPM" %measures['bpm'])
    plt.legend(loc=4framealpha=0.6) 
    plt.show() 
#Wrapper function
def process(datasethrwfs):
    filtersignal(dataset2.5fs5)
    rolmean(datasethrwfs)
    fit_peaks(datasetfs)
    calc_RR(datasetfs)
    check_peaks(dataset)
    calc_ts_measures(dataset)
    calc_fd_measures(datasetfs)


 

Posted by uniqueone
,

http://www.ninadthakoor.com/2012/03/03/matcv/


        //Transpose the opencv data to get row major data for matlab
        tmp=opencv.t();

opencv mat를 matlab mex 데이터로 변환할때는 .t()로 transpose시켜줘야 한다.



Using OpenCV functions in Matlab

I wrote Converter class few days back to simplify creating MEX files for OpenCV functions. Example of using the class follows in the next post.

Source for matcv.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef __MATCV__H__
#define __MATCV__H__
 
#include &quot;mex.h&quot;
#include &quot;matrix.h&quot;
#include &lt;cstring&gt;
#include &quot;opencvcv.h&quot;
#include &quot;opencvhighgui.h&quot;
#include &quot;boostbimap.hpp&quot;
 
class Converter{
public:
 Converter(mxArray* src, bool Interleve=true);
 Converter(cv::Mat&amp; src);
 
 operator cv::Mat();
 operator mxArray*();
 
private:
 enum{MATLAB_MXARRAY,OPENCV_MAT} _id;
 bool _interleve;
 
 cv::Mat opencv;
 mxArray* matlab;
 
 typedef boost::bimap&lt;mxClassID,unsigned char&gt; bmtype;
 bmtype _idmap;
 void _initidmap();
 
 void _matlab2opencv();
 void _opencv2matlab();
};
 
#endif //__MATCV__H__

Source for matcv.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include &quot;matcv.h&quot;
 
Converter::Converter(mxArray* src,bool Interleve):matlab(src),_id(MATLAB_MXARRAY),_interleve(Interleve){
    _initidmap();
}
Converter::Converter(cv::Mat&amp; src):opencv(src),_id(OPENCV_MAT){
    _initidmap();
}
 
Converter::operator cv::Mat()
{
    if(_id==OPENCV_MAT)
        return(opencv);
    _matlab2opencv();
    return(opencv);
}
 
Converter::operator mxArray*()
{
    if(_id==MATLAB_MXARRAY)
        return(matlab);
    _opencv2matlab();
    return(matlab);
}
 
void Converter::_initidmap()
{
    _idmap.insert(bmtype::value_type(mxINT8_CLASS,CV_8S));
    _idmap.insert(bmtype::value_type(mxUINT8_CLASS,CV_8U));
    _idmap.insert(bmtype::value_type(mxINT16_CLASS,CV_16S));
    _idmap.insert(bmtype::value_type(mxUINT16_CLASS,CV_16U));
    _idmap.insert(bmtype::value_type(mxINT32_CLASS,CV_32S));
    _idmap.insert(bmtype::value_type(mxSINGLE_CLASS,CV_32F));
    _idmap.insert(bmtype::value_type(mxDOUBLE_CLASS,CV_64F));
}
 
void  Converter::_opencv2matlab()
{
    //Is the data type supported?
    bmtype::right_map::const_iterator itr=_idmap.right.find(opencv.depth());
     
    //if not then
    if(itr==_idmap.right.end())
    {
        mexErrMsgTxt(&quot;OpenCV2Matlab:Unsupported data type.&quot;);
    }
     
    //Find the matlab data type
    mxClassID type=itr-&gt;second;
     
    //We support max 3 dimensions
    mwSignedIndex dims[3];
    dims[0]=opencv.rows;
    dims[1]=opencv.cols;
    dims[2]=opencv.channels();
     
    //if number of channels is 1, its a 2D array
    if(dims[0]&gt;0 &amp;&amp; dims[1]&gt;0 &amp;&amp; dims[2]==1)
    {
        //Create the array to be returned
        matlab=mxCreateNumericArray(2,dims,type,mxREAL);
        //Create opencv header for the matlab data
        cv::Mat tmp=cv::Mat(dims[1],dims[0],CV_MAKETYPE(opencv.depth(),1),mxGetData(matlab),0);
        //Transpose the opencv data to get row major data for matlab
        tmp=opencv.t();
         
        const mwSize* size=mxGetDimensions(matlab);
        mxAssert((opencv.rows==size[0])&amp;(opencv.cols==size[1]),&quot;OpenCV2Matlab:Conversion mismatch&quot;);
    }
    else
    {
        //Create the array to be returned
        matlab=mxCreateNumericArray(3,dims,type,mxREAL);
         
        //Seperate the channels
        std::vector&lt;cv::Mat&gt; chans(dims[2]);
        //cv::split(opencv,&amp;chans[0]);
        cv::split(opencv,chans);
         
        //Create opencv header as a &quot;flat&quot; image for the matlab data
        cv::Mat tmp=cv::Mat(dims[1]*dims[2],dims[0],CV_MAKETYPE(opencv.depth(),1),mxGetData(matlab),0);
         
        for(int i=0;i&lt;dims[2];i++)
        {
            //transpose the opencv channels image to row major matlab data
            cv::Mat tmp2=chans[i].t();
            //Copy the data to the flat matlab data
            tmp2.copyTo(tmp.rowRange(i*dims[1],(i+1)*dims[1]));
        }
         
        const mwSize* size=mxGetDimensions(matlab);
        mxAssert((opencv.rows==size[0])&amp;(opencv.cols==size[1])&amp;(opencv.channels()==size[2]),&quot;OpenCV2Matlab:Conversion mismatch&quot;);
    }  
}
 
void  Converter::_matlab2opencv()
{
    //find the corresponding corresponding opencv data type
    bmtype::left_map::const_iterator itr=_idmap.left.find(mxGetClassID(matlab));
     
    //No corresponding type?
    if(itr==_idmap.left.end()| mxIsComplex(matlab) | mxIsSparse(matlab))
    {
        std::string msg=&quot;Matlab2OpenCV:Unsupported data type:&quot;+(itr==_idmap.left.end()?std::string(mxGetClassName(matlab)):&quot;&quot;)
        +(mxIsComplex(matlab)?&quot; Complex&quot;:&quot;&quot;)+(mxIsSparse(matlab)?&quot; Sparse&quot;:&quot;.&quot;);
        mexErrMsgTxt(msg.c_str());
    }
     
    unsigned char type=itr-&gt;second;
     
    //Get number of dimensions
    const mwSize dims=mxGetNumberOfDimensions(matlab);
     
    //Cannot handle more that 3 dimensions
    if(dims&gt;3)
    {
        std::ostringstream o;
        o&lt;&lt;&quot;Matlab2OpenCV:Supports upto 3 dimensions. You supplied &quot;&lt;&lt;dims&lt;&lt;&quot;.&quot;;
        mexErrMsgTxt(o.str().c_str());
    }
     
    //Get actual dimensions
    const mwSize* size=mxGetDimensions(matlab);
     
    //Check if 2 or 3 dimentions
    if(dims==2)
    {
        //Create header for row major matlab data
        const cv::Mat donotmodify=cv::Mat(size[1],size[0],CV_MAKETYPE(type,1),mxGetData(matlab),0);
         
        //Transpose the data so that it is column major for opencv.
        opencv=donotmodify.t();
        mxAssert((opencv.rows==size[0])&amp;(opencv.cols==size[1]),&quot;Matlab2OpenCV:Conversion mismatch&quot;);
    }
    else
    {
        //Create header for the &quot;flat&quot; matlab data
        const cv::Mat donotmodify=cv::Mat(size[1]*size[2],size[0],CV_MAKETYPE(type,1),mxGetData(matlab),0);
         
        //Transpose the flat data
        cv::Mat flat=donotmodify.t();
         
        //Create vector of channels to pass to opencv merge operataion
        std::vector&lt;cv::Mat&gt; chans(size[2]);
         
        for(int i=0;i&lt;size[2];i++)
        {
            chans[i]=flat.colRange(i*size[1],(i+1)*size[1]);
        }
        cv::merge(chans,opencv);
        mxAssert((opencv.rows==size[0])&amp;(opencv.cols==size[1])&amp;(opencv.channels()==size[2]),&quot;Matlab2OpenCV:Conversion mismatch&quot;);
    }
}


Posted by uniqueone
,

http://stackoverflow.com/questions/27514658/way-to-send-opencv-mat-to-matlab-workspace-without-copying-the-data



When I write MEX files which use OpenCV functions it's easy to pass the data from MATLAB to the MEX environment without copying the data. Is there a way to return the data to MATLAB in the same manner? (That is, without copying the data and without causing MATLAB to crash...)

A simple example:

#include "mex.h"
#include "/opencv2/core.hpp"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,const mxArray *prhs[])
{

    Rows=mxGetM(prhs[0]);
    Cols=mxGetN(prhs[0]);
    Mat InMat(Cols,Rows,CV_64FC1,mxGetPr(prhs[0]));//Matlab passes data column-wise 
                                                   // no need to copy data - SUPER!

    InMat=InMat.t();//transpose so the matrix is identical to MATLAB's one

    //Make some openCV operations on InMat to get OutMat...


    //Way of preventing the following code??

    plhs[0]=mxCreateDoubleMatrix(OutMat.rows,OutMat.cols,mxREAL);
    double *pOut=mxGetPr(plhs[0]);

    for (int i(0);i<OutMat.rows;i++)
      for (int j(0);j<OutMat.cols;j++)
         pOut[i+j*OutMat.rows]=OutMat.at<double>(i,j);

}



-----------------------------------------

Usually I do the input and output just like that, attaching a pointer to deal with the input and looping over elements on output. But, I think the output can be done in a similar manner to the input, although not without a copy of some sort. The only way to avoid a copy is to create the output Mat with a pointer from a mxArray and operate on it inplace. That's not always possible, of course. But you can be graceful about how you copy the data out.

You can exploit the same trick of attaching a buffer to a cv::Mat that you use (me too!) to bring data in from MATLAB, but also to get it out. The twist on the trick to exporting the data is to use copyTojust right so that it will use the existing buffer, the one from the mxArray in plhs[i].

Starting with an input like this:

double *img = mxGetPr(prhs[0]);
cv::Mat src = cv::Mat(ncols, nrows, CV_64FC1, img).t(); // nrows <-> ncols, transpose

You perform some operation, like resizing:

cv::Mat dst;
cv::resize(src, dst, cv::Size(0, 0), 0.5, 0.5, cv::INTER_CUBIC);

To get dst into MATLAB: first transpose the output (for sake of reordering the data into col-major order) then create an output cv::Mat with the pointer from the plhs[0] mxArray, and finally call copyTo to fill out the wrapper Mat with the transposed data:

dst = dst.t(); // first!
cv::Mat outMatWrap(dst.rows, dst.cols, dst.type(), pOut); // dst.type() or CV_*
dst.copyTo(outMatWrap); // no realloc if dims and type match

It is very important to get the dimensions and data type exactly the same for the following call to copyTo to keep from reallocating outMatWrap.

Note that when outMatWrap is destroyed, the data buffer will not be deallocated because the reference count is 0 (Mat::release() does not deallocate .data).


Possible template (by no means bullet-proof!)

template <typename T>
void cvToMATLAB(cv::Mat mat, T *p)
{
    CV_Assert(mat.elemSize1() == sizeof(T));
    mat = mat.t();
    cv::Mat outMatWrap(mat.rows, mat.cols, mat.type(), p);
    mat.copyTo(outMatWrap);
}

This should be good for channels>1, as long as the size of the MATLAB array is in pixel order too (e.g. 3xMxN). Then use permute as needed.


Note about copyTo

The conditions under which copyTo will reallocate the destination buffer are if the dimensions or data type do not match:

opencv2\core\mat.hpp line 347 (version 2.4.10), with my comments:

inline void Mat::create(int _rows, int _cols, int _type)
{
    _type &= TYPE_MASK;
    if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
        return;    // HIT THIS TO USE EXISTING BUFFER!
    int sz[] = {_rows, _cols};
    create(2, sz, _type); // realloc!
}

So, just make sure you get the size and data type correct, and the data will end up in the mxArraybuffer instead of somewhere else. If you do it right, copyTo will use the buffer you specified, calling memcpy on each row.


Posted by uniqueone
,

http://stackoverflow.com/questions/7970988/print-out-the-values-of-a-mat-matrix-in-opencv-c

 

I want to dump the values of a matrix in OpenCV to the console using cout. I quickly learned that I do not understand OpenvCV's type system nor C++ templates well enough to accomplish this simple task.

Would a reader please post (or point me to) a little function or code snippet that prints a Mat?

Regards, Aaron

PS: Code that uses the newer C++ Mat interface as opposed to the older CvMat interface is preferential.

--------------------------------------

See the first answer to Accesing a matrix element in the "Mat" object (not the CvMat object) in OpenCV C++
Then just loop over all the elements in cout << M.at<double>(0,0); rather than just 0,0

Or better still with the new C++ interface (thanks to SSteve)

cv::Mat M;

cout << "M = "<< endl << " "  << M << endl << endl;

------------------------------

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <iomanip>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    double data[4] = {-0.0000000077898273846583732, -0.03749374753019832, -0.0374787251930463, -0.000000000077893623846343843};
    Mat src = Mat(1, 4, CV_64F, &data);
    for(int i=0; i<4; i++)
        cout << setprecision(3) << src.at<double>(0,i) << endl;

    return 0;
}

 

-------------------------------

Posted by uniqueone
,

my example.

img is dlib image variable. img22 is opencv image variable.

 

 

 

cv::Mat img22 = dlib::toMat(img);
 for(int i=0; i<250; i++)
 {
  for(int j=0; j<250; j++)
  {
   mexPrintf("%d ",img22.at<unsigned char>(i,j));
  }
  mexPrintf("\n");
 }

Posted by uniqueone
,
http://stackoverflow.com/questions/38180410/image-convert-to-grayscale

 

 

Image convert to grayscale

 

 

How can I convert a dlib::array2d to gray Image? The gray Image should be array2d or not? I never see a good dlib documentation.

 

----------------------------------------------

dlib::array2d is an image already, you can use it for any dlib's image functions

load image:

dlib::array2d<dlib::rgb_pixel> img_rgb;
dlib::load_image(img_rgb, "test_image.jpg");

convert to greyscale:

dlib::array2d<unsigned char> img_gray;
dlib::assign_image(img_gray, img_rgb);

converto to OpenCV Image (cv::Mat):

#include <dlib/opencv.h>
#include <opencv2/opencv.hpp>
cv::Mat img = dlib::toMat(img_gray);

get image from OpenCV:

#include <dlib/opencv.h>
#include <opencv2/opencv.hpp>
cv::Mat img = cv::imread("test_image.jpg")
dlib::cv_image<rgb_pixel> dlib_img(img); // only stores pointer, no deep copy

Documentation is here. There are a lot of well-documented examples, you should start from them. Special example about array2d

Posted by uniqueone
,

http://stackoverflow.com/questions/36908402/dlib-training-shape-predictor-for-194-landmarks-helen-dataset

 

DLIB : Training Shape_predictor for 194 landmarks (helen dataset)

 

I am training DLIB's shape_predictor for 194 face landmarks using helen dataset which is used to detect face landmarks through face_landmark_detection_ex.cpp of dlib library.

Now it gave me an sp.dat binary file of around 45 MB which is less compared to file given (http://sourceforge.net/projects/dclib/files/dlib/v18.10/shape_predictor_68_face_landmarks.dat.bz2) for 68 face landmarks. In training

  • Mean training error : 0.0203811
  • Mean testing error : 0.0204511

and when I used trained data to get face landmarks position, IN result I got..

enter image description here

which are very deviated from the result got from 68 landmarks

68 landmark image:

enter image description here

Why?

-----------------------------------------------------

Ok, looks like you haven't read the code comments (?):

shape_predictor_trainer trainer;
// This algorithm has a bunch of parameters you can mess with.  The
// documentation for the shape_predictor_trainer explains all of them.
// You should also read Kazemi's paper which explains all the parameters
// in great detail.  However, here I'm just setting three of them
// differently than their default values.  I'm doing this because we
// have a very small dataset.  In particular, setting the oversampling
// to a high amount (300) effectively boosts the training set size, so
// that helps this example.
trainer.set_oversampling_amount(300);
// I'm also reducing the capacity of the model by explicitly increasing
// the regularization (making nu smaller) and by using trees with
// smaller depths.  
trainer.set_nu(0.05);
trainer.set_tree_depth(2);

Have a look at the Kazemi paper, ctrl-f the string 'parameter' and have a read...

Posted by uniqueone
,
https://www.stereolabs.com/blog/index.php/tag/matlab/

 

아래 설명에 나온것처럼 cmake로 mex파일을 생성할때는, visual studio sln파일을 만든 후, 그 프로젝트를 빌드한 후, INSTALL을 빌드해주면 mex파일이 생성된다.

 

 

 

  • Right click on the project named ‘mexZED’ and select ‘Build’
  • Right click on the project named ‘INSTALL’ and select ‘Build’
  • ---------------------------------------------------

     

    Introduction

    The purpose of this post is to explain how to use the ZED stereo camera and its SDK to capture depth maps with Matlab. We use the ability of Matlab to execute C++ code through an intermediate file called MEXA file.

    You will find the complete source code on Stereolabs’ Github page.

    If you simply want to use the ZED stereo camera with Matlab (without the ZED SDK) you can refer to this article.

    Prerequisites

    You must have Matlab installed on your system and of course, the ZED SDK needs to be installed too.

    Code

    When downloading the source code from GitHub, you will find two subfolders. The first one, ‘matlab’, contains a file named ‘ZED_Camera.m’, a standard Matlab file wich will call the ZED functions. The second subfolder, ‘src’, contains the files to build the application.
    In the ‘mex’ subfolder, there is a file named ‘mexZED.cpp’ which contains the ZED SDK functions and interoperability with the Matlab format. This file is referred to as a MEX file. It re-implements the majority of the ZED SDK functions. This file is provided as a basic container and can be complemented with your own functions. Since Matlab does not handle image representation the same way the ZED SDK does, we need additional formatting functions.In the file ‘ZED_Camera.m’ the ZED functions are reachable through mexZED(‘..’). Check the ‘mexZED.cpp’ to see the list of functions available.

    Build procedure

    You now want to compile the mexZED.cpp file in a MEXA file format which can be used by Matlab. Usually, MEX files are compiled directly by Matlab but since we need to link several libraries (ZED, OpenCV) it is better to use CMake.
    On Linux

    Open a terminal in zed-Matlab directory and execute the following command:

    export MATLAB_ROOT=/usr/local/MATLAB/R2012b
    mkdir build
    cd build
    cmake ../src
    make
    make install
    On Windows

    You need to set the environment variable ‘MATLAB_ROOT’, to do this you can use an editor such as ‘Rapid Environment Editor’ or use the following procedure:

     

    • Click the Start button, right-click on ‘Computer’ and select ‘Properties’.
    • Click the ‘Advanced System Settings’ link in the left column.
    • In the System Properties window, click on the ‘Advanced’ tab, then click the ‘Environment Variables…’ button in the bottom of the window.
    • In the upper part of the window, add your definition to ‘User variables for..’
    • Click ‘New…’
    • Set ‘Variable name’ as MATLAB_ROOT
    • Set ‘Variable value’ to your own matlab root directory e.g. ‘C:\Program Files\MATLAB\R2014b’
    • Restart your computer.

     

     

     

    Then a common build procedure is used:

    • Open cmake-gui.
    • In “Where is the source code”, enter the path of the sources (e.g. ‘C:\Users\Peter\Documents\zed-matlab\src’)
    • In “Where to build the binaries”, enter the build directory (e.g. ‘C:\Users\Peter\Documents\zed-matlab\build’), and click the “Configure” button.
    • A dialog window asks you if CMAKE can create the folder “build” itself. Say yes.
    • Another dialog window will ask you the generator of your project. Choose Visual Studio. For example, we choose “Visual Studio 12 2013”. Click the “Finish” button.
    • CMAKE may take few seconds to configure the project. Then, some red lines should be displayed in the cmake-gui window.
    • Make sure that the message ‘MATLAB Found, MATLAB MEX will be compiled.’ is print, if not the variable environment MATLAB_ROOT can not be found, and you can not compile the project.
    • Click the “Generate” button.
    • CMAKE has just generated your project in the build folder. Now, you can close the cmake-gui window and go to the build folder.
    • Visual Studio files has been generated and a Visual Studio project file named “MEX.sln” too. Open it with Visual Studio.
    • Right click on the project named ‘mexZED’ and select ‘Build’
    • Right click on the project named ‘INSTALL’ and select ‘Build’

     

    Run the sample

    You can now find the generated MEXA file in the matlab directory (e.g. ‘\zed-matlab\matlab’), you can launch Matlab and run the ZED_Camera.m file.

    matlab

    Read More

    Posted by uniqueone
    ,

    아래와 같이 따라해보니 간단한 mex파일이 생성되었다.

    http://stackoverflow.com/questions/26220193/building-a-matlab-mex-file-in-visual-studio-gives-lnk2019-unresolved-external-s

    You need to create a Visual Studio project that produces DLLs (as opposed to console or GUI applications). MEX-files are basically shared libraries with a custom extension (*.mexw32 or *.mexw64 on Windows)

    The error message indicates that the linker cannot find the entry-point function main() for an executable, which does not exist for dynamic libraries.

    For what it's worth, you can run mex -v ... in MATLAB, that way it shows you the exact commands used to invoke the compiler and linker.


    EDIT:

    Step-by-step instructions:

    • create a new empty VS project to build DLLs (Visual C++ > Win32 > Win32 console application , (이름입력후 ok를 누른 후) then set the (application) type to DLL in the wizard)

    • Since we're working with MATLAB x64, we need to adjust project configuration to generate 64-bit binaries. From Build menu, select Configuration Manager. From the drop-down menu choose <New> to create a new platform configs, select x64 and accept.

    • follow the previous instructions you mentioned

    • add the C/C++ source code for the MEX-file

      #include "mex.h"
      void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
      {
          plhs[0] = mxCreateString("hello world");
      }
      
    • switch platform to "x64" in "Release" mode, and build the project. Now you should have a somefile.mexw64 MEX-file which you can call in MATLAB as a regular function.

    --------------------------------------------

    위의 instructions 은 아래이다. (http://stackoverflow.com/questions/16716821/how-to-build-mex-file-directly-in-visual-studio/16718578#16718578)

    After some experimenting with guidance from this page mentioned in the question, it seems like starting with an empty C++ project the following settings in the project's Property Pages are necessary and sufficient to build a working .mexw64 from Visual Studio 2010:

    Configuration properties -> General:
        Set Target Extension to .mexw64
        Set Configuration Type to Dynamic Library (.dll)
    
    Configureation poperties -> VC++ Directories:
        Add $(MATLAB_ROOT)\extern\include; to Include Directories
    
    Configuration properties -> Linker -> General:
        Add $(MATLAB_ROOT)\extern\lib\win64\microsoft; to Additional Library Directories
    
    Configuration properties -> Linker -> Input:
        Add libmx.lib;libmex.lib;libmat.lib; to Additional Dependencies
    
    Configuration properties -> Linker -> Command Line:
        Add /export:mexFunction to Additional Options
    

    $(MATLAB_ROOT) is the path to Matlab's root folder, eg. C:\Program Files\MATLAB\R2013a.

    So far this has only been tried from a solution created from scratch and built for Matlab 2013a 64-bit. I assume that to build for 32-bit one only needs to change both occurrences of 64 to 32. I will update the post when I have confirmed that this works for an existing solution.

    EDIT: As expected this works for projects added to existing solutions. Remember to set the new project to be dependent on the project that creates the library.

    Edit 2: Following this question I can confirm that the above steps work in Visual Studio 2012 and 2013 too.

    Posted by uniqueone
    ,

    ms-dos 창에서 boost가 있는 폴더로 간다. 그런 후 아래와 같은 명령어를 차례로 입력한다.

    -------------------

    bootstrap
    .\b2
    -------------------

    (http://www.boost.org/doc/libs/1_61_0/more/getting_started/windows.html#zip)를 참조.

     

     

     

    어떤사람은 아래와 같이 명령어를 입력했다고 한다

    "I built it from the MS visual studio command prompt by first executing the bootstrap command from inside the directory where boost is located and then using the bjam command. –"

    (http://stackoverflow.com/questions/19303430/cmake-cannot-find-boost-libraries)

    'C,C++ > Other Library' 카테고리의 다른 글

    [boost] CMake is not able to find BOOST libraries  (0) 2016.09.20
    [boost]CMake not finding Boost  (0) 2016.09.20
    Posted by uniqueone
    ,

    https://forum.qt.io/topic/69007/compile-dlib-on-windows

     

    I try to use dlib in Qt project on Windows. After downloading I did this in the dlib root:

    cd examples
    mkdir build
    cd build
    cmake .. -G"Visual Studio 14 2015 Win64" 
    cmake --build . --config Release
    

    And this(again in dlib root):

    mkdir build
    cd build
    cmake .. -G"Visual Studio 14 2015 Win64" -DCMAKE_INSTALL_PREFIX=D:\dlib_build
    cmake --build . --config Release --target install
    

    My .pro file:

    QT += core
    QT -= gui
    
    CONFIG += c++11
    
    TARGET = dlibWin2
    CONFIG += console
    CONFIG -= app_bundle
    
    TEMPLATE = app
    
    SOURCES += main.cpp
    
    INCLUDEPATH += "D:\dlib_build\include"
    LIBS += -L"D:\dlib_build\lib" -ldlib
    QMAKE_CXXFLAGS_RELEASE += /arch:AVX
    QMAKE_CXXFLAGS += -DDLIB_JPEG_SUPPORT
    

    main.cpp:

    #include <QCoreApplication>
    #include <dlib/image_processing/frontal_face_detector.h>
    #include <dlib/image_processing/render_face_detections.h>
    #include <dlib/image_processing.h>
    #include <dlib/gui_widgets.h>
    #include <dlib/image_io.h>
    #include <iostream>
    
    
    using namespace dlib;
    using namespace std;
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
    
        try
        {
            frontal_face_detector detector = get_frontal_face_detector();
        }
        catch (exception& e)
        {
            cout << "\nexception thrown!" << endl;
            cout << e.what() << endl;
        }
        return a.exec();
    }
    

    Compilation output for MSVC2015 64bit Release:

    D:\dlib_build\include\dlib\config.h:19: Warning: C4005: DLIB_JPEG_SUPPORT
    

    Runtime output for MSVC2015 64bit Release:

    The program has unexpectedly finished... Exited with code -1073741795
    

    Please note that I did this after Windows reinstalling, and before this I got absolutely the same issue.

    How can I solve this or how can I use dlib in Qt on Windows?

    Posted by uniqueone
    ,
    http://stackoverflow.com/questions/24173330/cmake-is-not-able-to-find-boost-libraries

     

     

    I tried everything, Like:

    1. Configure Environment variable
    2. Make Fresh build
    3. Re-install BOOST from source
    4. sudo apt-get install libboost-all-dev

    But still getting following Errors:

    CMake Error at /usr/share/cmake-2.8/Modules/FindBoost.cmake:1131 (message):
     Unable to find the requested Boost libraries.
    
     Unable to find the Boost header files.  Please set BOOST_ROOT to the root
     directory containing Boost or BOOST_INCLUDEDIR to the directory containing
     Boost's headers.
    Call Stack (most recent call first):
       CMakeLists.txt:147 (find_package)
    
    
    CMake Error at /usr/share/cmake-2.8/Modules/FindBoost.cmake:1131 (message):
    Unable to find the requested Boost libraries.
    
    Unable to find the Boost header files.  Please set BOOST_ROOT to the root
    directory containing Boost or BOOST_INCLUDEDIR to the directory containing
    Boost's headers.
    

    Source code directory for boost: /usr/local/src/boost_1_45_0 Boost Library path: /usr/local/libBoost Header file: /usr/local/include/boost

    Here is bashrc file:

    BOOST_ROOT="/usr/local/src/boost_1_45_0"
    Boost_LIBRARY_DIRS="/usr/local/lib"
    BOOST_INCLUDEDIR="/usr/local/src/boost_1_45_0"
    

    How to solve these Errors? Am i missing something?

    Edit:

    cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN -DBOOST_ROOT=/usr/local/src/boost_1_45_0 -DBOOST_INCLUDEDIR=/usr/local/include/boost -DBOOST_LIBRARYDIR=/usr/local/lib -DPYTHON_LIBRARIES=/usr/local/lib/python2.7 -DPYTHON_INCLUDE_DIRS=/usr/include/python2.7 -DCMA-DRDK_BUILD_PYTHON_WRAPPERS=
    

    ---------------------------------------------------------

    Can you show the output of CMake if you do cmake . -DBoost_DEBUG=ON? – Fraser Jun 11 '14 at 22:03
    2  
    Looks like it's not picking up the environment variables. See lines 8-10 of your output. You can try passing these as CMake variables. Maybe even just BOOST_ROOT would be enough: cmake . -DBOOST_ROOT=/usr/local – Fraser Jun 11 '14 at 22:10
    1  
    Be good to know what the Boost problem was. As for Python while cross-compiling, I can't really help too much. It looks like you can disable CMake trying to find Python by editing the CMakeLIsts.txt file around line 114, but if they've made it required, probably it's being used unconditionally somewhere else, and you'll then just get a failure at that point. Like I said, probably time for a new question :-) – Fraser Jun 11 '14 at 23:18
    4  
    @AmitPal Please add an answer yourself instead of editing the answer into your question, that way people can see that the question is answered. – Andreas Haferburg Jun 12 '14 at 12:51
    4  
    @AmitPal - Did that last line under EDIT fix the problem? If, YES, then answer your own question so people will the the question is answered, as Andreas Haferburg said in his comment above. – Patricia Apr 9 '15 at 15:52

     

    -----------------------------------------------

    Try to complete cmake process with following libs:

    sudo apt-get install cmake libblkid-dev e2fslibs-dev libboost-all-dev libaudit-dev

    -----------------------------------------------------

    I'm using this to set up boost from cmake in my CMakeLists.txt. Try something similar (make sure to update paths to your installation of boost).

    SET (BOOST_ROOT "/opt/boost/boost_1_57_0")
    SET (BOOST_INCLUDEDIR "/opt/boost/boost-1.57.0/include")
    SET (BOOST_LIBRARYDIR "/opt/boost/boost-1.57.0/lib")
    
    SET (BOOST_MIN_VERSION "1.55.0")
    set (Boost_NO_BOOST_CMAKE ON)
    FIND_PACKAGE(Boost ${BOOST_MIN_VERSION} REQUIRED)
    if (NOT Boost_FOUND)
      message(FATAL_ERROR "Fatal error: Boost (version >= 1.55) required.")
    else()
      message(STATUS "Setting up BOOST")
      message(STATUS " Includes - ${Boost_INCLUDE_DIRS}")
      message(STATUS " Library  - ${Boost_LIBRARY_DIRS}")
      include_directories(${Boost_INCLUDE_DIRS})
      link_directories(${Boost_LIBRARY_DIRS})
    endif (NOT Boost_FOUND)
    

    This will either search default paths (/usr, /usr/local) or the path provided through the cmake variables (BOOST_ROOT, BOOST_INCLUDEDIR, BOOST_LIBRARYDIR). It works for me on cmake > 2.6.

    shareimprove this answer

    seems the answer is in the comments and as an edit but to clarify this should work for you:

    export BUILDDIR='your path to  build directory here'
    export SRCDIR='your path to source dir here'
    export BOOST_ROOT="/opt/boost/boost_1_57_0"
    export BOOST_INCLUDE="/opt/boost/boost-1.57.0/include"
    export BOOST_LIBDIR="/opt/boost/boost-1.57.0/lib"
    export BOOST_OPTS="-DBOOST_ROOT=${BOOST_ROOT} -DBOOST_INCLUDEDIR=${BOOST_INCLUDE} -DBOOST_LIBRARYDIR=${BOOST_LIBDIR}"
    (cd ${BUILDDIR} && cmake ${BOOST_OPTS} ${SRCDIR})
    

    you need to specify the arguments as command line arguments or you can use a toolchain file for that, but cmake will not touch your environment variables.

    shareimprove this answer

    I just want to point out that the FindBoost macro might be looking for an earlier version, for instance, 1.58.0 when you might have 1.60.0 installed. I suggest popping open the FindBoost macro from whatever it is you are attempting to build, and checking if that's the case. You can simply edit it to include your particular version. (This was my problem.)

     

    'C,C++ > Other Library' 카테고리의 다른 글

    [boost] boost build하기  (0) 2016.09.21
    [boost]CMake not finding Boost  (0) 2016.09.20
    Posted by uniqueone
    ,
    http://stackoverflow.com/questions/13280823/cmake-not-finding-boost

     

     

     

     

    I saw at least 3 questions with the same title as this question. Each of them had a different answer that worked for the OP but not for me, so I am sorry to repeat the question...

    I am trying to install CGAL. They describe their installation process as ever-so-simple here, section 6.1. When I run cmake-gui and then click configure, I get the following output

    CMake Error at D:/program files/CMake 2.8/share/cmake-2.8/Modules/FindBoost.cmake:1192 (message):
      Unable to find the requested Boost libraries.
    
      Boost version: 1.51.0
    
      Boost include path: D:/program files/boost_1_51
    
      The following Boost libraries could not be found:
    
              boost_thread
              boost_system
    
      No Boost libraries were found.  You may need to set BOOST_LIBRARYDIR to the
      directory containing Boost libraries or BOOST_ROOT to the location of
      Boost.
    Call Stack (most recent call first):
      cmake/modules/CGAL_SetupBoost.cmake:6 (find_package)
      cmake/modules/CGAL_SetupDependencies.cmake:85 (include)
      CMakeLists.txt:590 (include)
    

    But I DID set up BOOST_ROOT, in cmake's gui, to D:/program files/boost_1_51, which exists. And the two libraries it mentions are definitely installed. What is happening here? What do I need to do?

    EDIT: Attached is the output when running cmake -DBoost_DEBUG=ON

    D:\program files\CGAL-4.1>cmake -DBoost_DEBUG=ON
    == Setting paths ==
    -- Build CGAL from release in directory CGAL-4.1
    -- Packagenames: CGAL-4.1
    == Setting paths (DONE) ==
    
    == Generate version files ==
    -- CGAL_MAJOR_VERSION=4
    -- CGAL_MINOR_VERSION=1
    -- CGAL_BUGFIX_VERSION=0
    -- CGAL_SONAME_VERSION=10
    -- CGAL_SOVERSION     =10.0.0
    -- CGAL_REFERENCE_CACHE_DIR=
    -- Building shared libraries
    -- Targetting Visual Studio 10 Win64
    -- Target build enviroment supports auto-linking
    -- Using VC10 compiler.
    -- Generator uses intermediate configuration directory: $(Configuration)
    -- USING CMake version: 2.8.10
    -- System: Windows
    == Generate version files (DONE) ==
    
    == Set up flags ==
    -- Build type: Release
    -- USING CXXFLAGS = ' /DWIN32 /D_WINDOWS /W3 /Zm1000 /GR /EHsc -D_CRT_SECURE_NO_
    DEPRECATE -D_SCL_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_
    WARNINGS /fp:strict /fp:except- /MD /O2 /Ob2 /D NDEBUG'
    -- USING LDFLAGS = ' /STACK:10000000 /machine:x64  /INCREMENTAL:NO'
    == Set up flags (DONE) ==
    
    == Detect external libraries ==
    -- External libraries supported: GMP;MPFR;ZLIB;OpenGL;LEDA;MPFI;RS;RS3;OpenNL;TA
    UCS;Eigen3;BLAS;LAPACK;QGLViewer;ESBTL;Coin3D;NTL;IPE
    -- Preconfiguring library: GMP ...
    -- GMP has been preconfigured:
    --   CGAL_UseGMP-file:
    --   GMP include:      D:/program files/CGAL-4.1/auxiliary/gmp/include
    --   GMP libraries:    D:/program files/CGAL-4.1/auxiliary/gmp/lib/libgmp-10.lib
    
    --   GMP definitions:
    -- USING GMP_VERSION = '5.0.1'
    -- Preconfiguring library: MPFR ...
    -- MPFR has been preconfigured:
    --   CGAL_UseMPFR-file:

    ---------------------------------

     

     

     

     

    Your output shows that CMake is searching for the libraries in the following places:

    D:/program files/boost_1_51/bin/lib
    D:/program files/boost_1_51/bin/stage/lib
    D:/program files/boost_1_51/lib
    D:/program files/boost_1_51/../lib
    D:/program files/boost_1_51/stage/lib
    C:/boost/lib
    C:/boost
    C:\Program Files (x86)/boost/boost_1_51_0/lib
    C:\Program Files (x86)/boost/boost_1_51/lib
    C:\Program Files (x86)/boost/lib
    C:\Program Files (x86)/boost
    /sw/local/lib
    

    It also shows that it's expecting the libraries to be named in a certain way. For example, the release version of Boost.Thread:

    boost_thread-vc100-mt-1_51
    boost_thread-vc100-mt
    boost_thread-mt-1_51
    boost_thread-mt
    boost_thread
    

    If your boost libraries do exist in one of the searched locations, then it's probably the name of the library that's the problem. You can adjust the expected name of the boost libs by setting the appropriate CMake variables relevant to the FindBoost module

    For example, if you built boost using bjam with link=static threading=multi then in your CMakeLists.txt before find_package(Boost ...) you'll want to do

    set(Boost_USE_STATIC_LIBS ON)
    set(Boost_USE_MULTITHREADED ON)
    

    or invoke cmake with -DBoost_USE_STATIC_LIBS=ON -DBoost_USE_MULTITHREADED=ON

    Edit

    As @noam has pointed out in the comments below, in this particular case, it appears that CGAL requires the shared (dll) versions of the boost libs; passing -DBoost_USE_STATIC_LIBS=ON on the command line has no effect.

    shareimprove this answer
        
    I am using a university computer which already has boost on it. How can I know how did they compile boost (I really have no one to ask :) ) – olamundo Nov 8 '12 at 3:22
        
    @noam It can usually be deduced from the libraries' names. What is the full name and path of say the debug and release versions of Boost.Thread there? – Fraser Nov 8 '12 at 3:36
        
    I hope I understand you correctly: libboost_thread-vc100-mt-gd-1_51.lib and libboost_thread-vc100-mt-1_51.lib – olamundo Nov 8 '12 at 3:40
        
    @noam OK - the libraries are static (you can tell because they begin with "lib" - see Boost's getting started guide) so you need Boost_USE_STATIC_LIBS set to ON. In your output above, you can see that you currently have this value set to OFF. Once you do that, assuming the libs are actually in one of the search paths listed in my answer, it should all work. – Fraser Nov 8 '12 at 3:52
        
    Nope, it doesn't work. The libs are in D:\program files\boost_1_51\lib, but it still outputs the same error, when running cmake -DBoost_USE_STATIC_LIBS=ON. (Thank you for your patience, by the way) – olamundo Nov 8 '12 at 4:10

    I had this error but have progressed.

    I was using the cmake-gui, then I ticked the checkbox "Advanced" (between checkbox "Grouped" and button "Add Entry"), then I ticked the newly seen checkbox "CGAL_Boost_USE_STATIC_LIBS".

    You may need to press "Configure" an extra time or two before the extra options are revealed.

    shareimprove this answer

    Today I tried installing CGAL with Boost 1.57 x64 on Windows and encountered the same problem. I installed boost via pre-build binaries and the .lib files that CMake searches for are in the lib64-msvc-12.0 folder. Therefore adding BOOST_LIBRARYDIR=.../boost_1_57_0/lib64-msvc-12.0 to CMake options was the solution for me.

    shareimprove this answer
        
    Thanks, same here with boost 1.60 x64 binary install on Windows 7 and CGAL 1.47. I addedBOOST_LIBRARYDIR=C:\boost\lib64-msvc-14.0 in my case. – Paul Jurczak Jan 3 at 7:06 
    1. CGAL use the shared boost libraries. So, the libraries like "libboost_thread-vc100-mt-p-1_49.lib" is a statically linked library.

    2. It's because cmake(I used v2.8.9) can not read the name of boost libraries correctly. When I changed the library names boost_thread-vc100-mt-p-1_49.dll and boost_thread-vc100-mt-p-1_49.lib to boost_thread-vc100-mt-1_49.dll and boost_thread-vc100-mt-1_49, respectively, it fixed the problem.

    shareimprove this answer
    1  
    For reference: Do NOT do this. The naming reflects how boost was compiled. So you need to set the correct options for the Find module or you will end up with problems of any kind (using debug versions for release, multi-threaded for single-threaded etc) – Flamefire Jan 11 at 9:54

    'C,C++ > Other Library' 카테고리의 다른 글

    [boost] boost build하기  (0) 2016.09.21
    [boost] CMake is not able to find BOOST libraries  (0) 2016.09.20
    Posted by uniqueone
    ,

    http://kaylab.tistory.com/1

    http_kaylab.tistory.com_1.pdf

     

     

    위 사이트를 따라하니 오류없이 되었다.

    단 main.cpp를 다음과 같이 씀.

     

    #include <opencv2/core/mat.hpp>
    #include <opencv2/imgcodecs.hpp>
    #include <opencv2/imgproc.hpp>
    #include <opencv2/highgui.hpp>

    using namespace cv;
    using namespace std;

    int main()
    {
     return 0;
    }

     

    또는

    #include <opencv2/highgui.hpp>

    using namespace cv;

    int main()
    {
     IplImage* image;
     image = cvLoadImage("Tulips.jpg", 1);

     cvNamedWindow("W_Tulips", 1);
     cvShowImage("W_Tulips", image);

     cvWaitKey(0);
     cvDestroyWindow("W_Tulips");
     return 0;
    }

     

     

     

    -------------------------

    환경: OpenCV 3.1, Visual Studio 2015, 2013

     

    ※ OpenCV 는 c:\Opencv_3.1 에 설치되어 있는걸로 가정합니다.

     

     

    1. 프로젝트에서 마우스 우클릭 -> 속성

     

     

     

    2. 구성에서 32bit, x86 관련 설정을 지워야 합니다. 플랫폼 콤보 박스를 선택합니다.

    ※ OpenCV 3.1 은 32bit dll 이 없습니다. 소스를 가지고 직접 컴파일 하면 가능하다고 알고있는데, 확실하진 않습니다.

     

     

    3. 편집 메뉴 클릭

     

     

     

    4. x86을 선택하고 제거 버튼을 클릭합니다.

     

     

     

    5. [활성 솔루션 플랫폼] 콤보박스 아래 [플랫폼] 콤보박스를 클릭하여 [편집] 메뉴를 클릭합니다.

     

     

     

    6. Win32 를 선택 후 제거 버튼을 클릭합니다.

     

     

     

    7. 닫기 버튼을 클릭하여 구성관리자를 닫습니다.

     

     

     

    7.5. [구성] 콤보 박스를 [모든 구성] 으로 변경합니다.

         Debug 로 둔 채로 수정하면 Release 로 변경 후 한번 더 설정해야 합니다.

     

    8. 왼쪽 구성 트리에서 [C/C++] 노드를 선택하고 디렉터리 콤보박스의 편집 메뉴를 클릭합니다.

     

     

     

    9. 줄 추가 버튼을 클릭 한 후 새로 생긴 줄(2번) 의 오른쪽 끝 ... 버튼을 클릭합니다.

     

     

     

    10. C:\opencv_3.1\build\include 경로를 찾아가 폴더선택 버튼을 클릭합니다.

     

     

     

    11. 계속해서 하위 디렉터리인 C:\opencv_3.1\build\include\opencv 와 C:\opencv_3.1\build\include\opencv2 경로를 추가합니다.

     

     

     

    12. 왼쪽 트리 메뉴에서 링커 노드를 선택 후 추가 라이브러리 디렉터리 콤보박스에서 편집 메뉴를 클릭합니다.

     

     

     

    13. C:\opencv_3.1\build\x64\vc14\lib 경로를 찾아가 폴더 선택 버튼을 클릭합니다.

    ※ Visual Studio 2013 일 경우 C:\opencv_3.1\build\x64\vc12\lib 경로를 선택합니다.

     

     

     

    14. 구성 콤보박스를 Debug 로 변경합니다.

     

     

     

    15. 지금까지 설정한 내용을 저장하겠냐고 물어봅니다. 예(Y) 버튼을 클릭합니다.

     

     

     

    16. 왼쪽 트리 메뉴에서 입력 노드를 선택 후 추가 종속성 콤보박스를 클릭 후 편집 메뉴를 클릭합니다.

     

     

     

    17. opencv_world310d.lib 를 클릭 후 확인 버튼을 클릭합니다. (디버그에 경우에는 이름 마지막에 d가 붙은 lib 를 참조합니다.)

     

     

     

    18. 구성 콤보 박스를 Release 로 변경합니다. 위와 같이 저장 하겠냐는 메세지가 나오면 예(Y) 버튼을 클릭합니다.

     

     

     

    19. opencv_world310.lib (이번엔 이름 마지막에 d가 없습니다.) 을 입력하고 확인 버튼을 클릭합니다.

     

     

     

    20. stdafx.h 헤더에 다음과 같은 구문을 추가합니다.

    #include "opencv2\opencv.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"

    using namespace cv;
    using namespace std;

     

     

     

    정상적으로 컴파일이 된다면 구성 완료입니다

    Posted by uniqueone
    ,

    http://zacurr.tistory.com/553

     

    http_zacurr.tistory.com_553.pdf

     

    위 사이트에 나와있는대로 opencv를 cmake로 빌드할때, opencv_contrib도 다운받아서 같이 빌드했다.

    아래사이트에도 나옴. 

    https://github.com/opencv/opencv_contrib/blob/master/README.md

    1. start cmake-gui

    2. select the opencv source code folder and the folder where binaries will be built (the 2 upper forms of the interface)

    3. press the configure button. you will see all the opencv build parameters in the central interface

    4. browse the parameters and look for the form called OPENCV_EXTRA_MODULES_PATH (use the search form to focus rapidly on it)

    5. complete this OPENCV_EXTRA_MODULES_PATH by the proper pathname to the <opencv_contrib>/modules value using its browse button.

    6. press the configure button followed by the generate button (the first time, you will be asked which makefile style to use)

    7. build the opencv core with the method you chose (make and make install if you chose Unix makfile at step 6)

    8. to run, linker flags to contrib modules will need to be added to use them in your code/IDE. For example to use the aruco module, "-lopencv_aruco" flag will be added.

    Posted by uniqueone
    ,

     

    Error using mex
       Creating library example_mex_function.lib and object example_mex_function.exp
    example_mex_function.obj : error LNK2019: unresolved external symbol utIsInterruptPending referenced in function "void __cdecl dlib::check_for_matlab_ctrl_c(void)" (?check_for_matlab_ctrl_c@dlib@@YAXXZ)
    example_mex_function.mexw64 : fatal error LNK1120: 1 unresolved externals

     

    이런 에러가 떠서 검색하여 아래와 같이 하니 됐다.

     

    mex -O "example_mex_function.cpp" -I"D:\Research\dlib\dlib-19.0" "C:\Program Files\MATLAB\R2016a\extern\lib\win64\microsoft\libut.lib"

    Posted by uniqueone
    ,
    http://darkblitz.tistory.com/category/%EC%82%BD%EC%A7%88%EC%9D%BC%EA%B8%B0?page=2

     

     

    Energy minimization 부분을 살펴보다 관련 소스를 얻어 컴파일하려고 하니 아래와 같은 오류가 발생하였다.


     error LNK2019: unresolved external symbol utIsInterruptPending referenced in function...


    utIsInterruptPending가 extern으로 선언되어 있으나 링크되지 않아서 생기는 문제였다.


    utIsInterruptPending가 어디에 쓰는 함수인고 하니, Ctrl+C가 입력되었을 때, 이를 처리하는 함수라고 한다.


    utIsInterruptPending는 undocumented MATLAB API로 libut.dll에 구현되어 있으며, libut.lib를 mex 컴파일시에 링크해주면 되겠다. libut.lib는 기본적으로 mex에서 링크하지 않고 있으므로 -l옵션을 이용하여 추가해 주어야한다. 다음과 같이 하면 되겠다.


    mex blahblah.cpp -lut


    출처: http://www.caam.rice.edu/~wy1/links/mex_ctrl_c_trick/

     

    Posted by uniqueone
    ,
    https://victorfang.wordpress.com/2011/09/06/

     

    아래의 코드에서

    원래는 cc[i*n + j] = aa[i*n + j] + bb[i*n + j];가 comment돼 있으나, 이걸 풀고
    //C[i*n + j] = A[i*n + j] + B[i*n + j]; 이것을 comment시켜야 mex가 된다.

     

    To access the variables, you need to associate a pointer to the data in the mxArray. Once you do this, accessing the variables is very simple.


    a = mxGetPr(a_in_m);
    b = mxGetPr(b_in_m);
    c = mxGetPr(c_out_m);
    d = mxGetPr(d_out_m);

    Now it is possible to access the arrays with standard C or C++ [] notation. There are three important things to remember though:

    • You use 0-based indexing as always in C
    • You still use column-first indexing like in Matlab, though
    • To access the arrays, you use linear indexing (you can’t use [x][y], you have to use [y+x*dimy]

    With those three things in mind, go crazy. You can use standard C libraries (as long as you include them). You can use for loops as much as your heart desires, and your code will be much, much faster than its Matlab equivalent.

     

     

    Note that if we access using C[x] , we will get this error. In other words, we need to define another pointer to access the input memory space using: double *cc = mxGetPr(C);

     

    >> mex mextest.cpp
    mextest.cpp
    mextest.cpp(36) : error C2036: ‘mxArray *’ : unknown size
    mextest.cpp(36) : error C2036: ‘const mxArray *’ : unknown size
    mextest.cpp(36) : error C2036: ‘const mxArray *’ : unknown size
    mextest.cpp(36) : error C2676: binary ‘+’ : ‘const mxArray’ does not define this operator or a conversion to a type acceptable to the predefined operator

    C:\PROGRA~2\MATLAB\R2010B\BIN\MEX.PL: Error: Compile of ‘mextest.cpp’ failed.

    ??? Error using ==> mex at 208
    Unable to complete successfully.

     

     

     

    My working code:

    #include “mex.h”

    void mexFunction(int nlhs, mxArray *plhs[],
    int nrhs, const mxArray *prhs[])
    {
    /* more C/C++ code … */
    /* Check for proper number of arguments */
    if (nrhs != 2) {
    mexErrMsgTxt(“Two input arguments required.”);
    } else if (nlhs > 1) {
    mexErrMsgTxt(“Too many output arguments.”);
    }

    const mxArray *A = prhs[0];
    const mxArray *B = prhs[1];

    /* Check the dimensions of Y.  Y can be 4 X 1 or 1 X 4. */
    int m = mxGetM(A);
    int n = mxGetN(A);

    if (!mxIsDouble(A) || mxIsComplex(A) ) {
    mexErrMsgTxt(“YPRIME requires that Y be a 4 x 1 vector.”);
    }

    /* Create a matrix for the return argument */
    mxArray *C;
    C = plhs[0] = mxCreateDoubleMatrix(m, n, mxREAL);

    double *cc = mxGetPr(C);
    double *aa = mxGetPr(A);
    double *bb = mxGetPr(B);

    for(int i=0; i<m; i++){
    for(int j=0; j<n; j++){
    //cc[i*n + j] = aa[i*n + j] + bb[i*n + j];
    C[i*n + j] = A[i*n + j] + B[i*n + j];
    }
    }

    }

    Posted by uniqueone
    ,
    http://stackoverflow.com/questions/5622894/how-do-i-link-a-64-bit-matlab-mex-file-to-opencv-libraries

     

    mexFunction내에서 opencv가 라이브러리로 있을 때, mex 어떻게 시키는지 참고할수 있었음.

     

     

    Normally in MATLAB I can compile a mex file which uses OpenCV functions using:

    mex -O "mxFunc.cpp" -I"C:\OpenCV2.1\include/opencv" -L"C:\OpenCV2.1\lib" -lcv210 -lcvaux210 -lcxcore210 -lhighgui210

    However, having switched to a 64-bit version of MATLAB, I now get unresolved symbols, e.g.

    mxFunc.obj : error LNK2019: unresolved external symbol cvReleaseImage referenced in function mexFunction

    How can I fix this?

    System: Windows 7 64-bit; MSVC 2005; MATLAB R2010b 64-bit; OpenCV 2.1.0.

     

    -----------------------------------------------------------------------------------

    Generally: You need to recompile the used libraries in 64-bit.

    As far as I know, it's not enough. If you use STL (and the OpenCV uses a lot) you need to use the same CRT version what the Matlab uses. So you need to use the same version of MSVC what the Mathworks guys...

    You can check the dependency of the libmex.dll to figure out which CRT is needed. After it you need to install the proper Visual C++ (normally the free version is enough).

    -----------------------------------

    Using 64-bit libraries worked. I had to configure a new 64-bit MSVC solution using CMAKE, naming the "Generator" as "Visual Studio 8 2005 Win64". I don't know whether the compiler that I used was the same as that used to generate libmex.dll, but it worked anyway. – user664303 Apr 12 '11 at 10:23
        
    @user664303: The 32-bit version of the 2010a/20010b uses VS 2005. I suppose they use the same version for the 64-bit. You were lucky. :) – tr3w Apr 15 '11 at 16:54

    Posted by uniqueone
    ,
    http://hiraclid.blogspot.kr/2016/06/windows-visual-studiodlib.html

     

     

    요약

    0. Visual Studio Express 2015버전을 설치한다. face detection 또는 facelandmarks detection 이용하려면 opencv도 설치해야한다. (matlab으로 lbp뽑으려면 vlfeat도 설치해야. vlfeat도 업데이트되어 20180328현재 다시 새버전으로 설치. vlfeat를 쓰려면 mex파일로 만들어야하는데, 이 때 윈도우용 mex컴파일러가 필요하다. mex컴파일러 설치방법은 https://www.mathworks.com/matlabcentral/answers/233850-how-can-i-install-sdk-7-1-on-windows-10 참조)

     

    1. dlib 파일 (예:dlib-19.10)과 cmake 파일 (예:cmake-3.7.0-rc1-win32-x86)을 다운받아 압축을 푼다.

    2. 윈도우 커맨드창을 열고 dlib-19.10\examples 경로로 이동한 후 bulid폴더를 만든다.

    [D:\Research\dlib\dlib-19.10\examples>mkdir build]

    3. build폴더로 이동한다. [D:\Research\dlib\dlib-19.10\examples>cd build]

    4. 아래와 같이 [cmake.exe의절대경로 -G "비주얼스튜디오버전" ..]를 입력한다. 가장 뒤에 ' ..'를 꼭 써줘야한다.

    [D:\Research\dlib\cmake-3.7.0-rc1-win32-x86\bin\cmake.exe -G "Visual Studio 14 2015 Win64" ..]

    5. cmake로 컴파일한다. 시간이 5분정도? 걸린다.

    [D:\Research\dlib\dlib-19.10\examples\build>D:\Research\dlib\cmake-3.7.0-rc1-win32-x86\bin\cmake.exe --build . --config Release]

    컴파일이 끝나고 가장 끝에 '경고 3개, 오류 0개'라고 뜨면 성공한 것이다.

     

     

     

    아래 예제캡춰에서 4번식 가장 뒤에 ' ..'를 꼭 써줘야한다.

     

     

    Windows / Visual Studio 환경에 dlib의 도입 방법

    안녕하세요. 
    오늘은 이미지 처리 및 기계 학습, 얼굴 인식 등의 편리한 고성능 기능을 가진 라이브러리 "dlib"를 사용하여 다양한 시도했기 때문에 그 도입 방법을 비망록으로 정리해 두려고합니다. 

    왜 Windows 환경에 도입하는 방법에 관한 기사가 거의 없었기 때문에, 모처럼 이니까 블로그에 올리려고 생각 이르렀습니다. 


    내 환경인데, Windows 10에서 Visual Studio 2012를 사용하고 있습니다. 
    dlib 버전은 2016 년 현재 최신 (dlib 18.18)를 시도했습니다. 

    다음 단계입니다. 



    우선 http://dlib.net/ 에서 dlib 다운로드. zip 파일로 다운로드 할 수 있기 때문에 해동하십시오. 이어 dlib을 시험하기 위해 제대로 컴파일해야합니다. 그래서 공식적으로는 cmake를 사용하여 컴파일 할 것을 권장하고 있습니다. http://dlib.net 의 How to compile ( http://dlib.net/compile.html )에도 기재되어있는 링크 ( https://cmake.org/ )에서 cmake를 다운로드하고 있습니다. (이미 cmake를 가지고있는 사람은 특히 새로운 것일 필요도 없습니다) 2016 년 6 월 현재이라고 cmake은 3.5.2이 최신 버전입니다. Source distributions 대신 Binary distributions 분에서 Windows 용 ZIP를 다운로드하십시오. zip을 다운로드 한 후 압축을 적당한 장소에 보관하십시오. cmake를 사용하면 GUI에서 빌드 파일을 만들 수 있습니다 만, 이번은 dlib의 공식 권장하고있는 방법에 따른 명령 프롬프트에서 cmake에 의한 컴파일합니다. How to compile ( http://dlib.net/compile.html )과 같이갑니다. 명령 프롬프트 (Windows 키를 눌러 "cmd"를 치면 나옵니다.)를 사용하여 위의 ① ~ ⑤의 명령을 칠뿐입니다. 그러나 위는 cmake의 경로와 dlib 경로를 생략하고 있기 때문에 완전히 그대로 치면 좋은 것은 아닙니다. 특히 Visual Studio에서 64bit 응용 프로그램을 구현하려는 경우에는 ④의 명령이 다음의 것이됩니다. 그러나이 ④도 Visual Studio 2010 명령이므로주의. Visual Studio 2012이면 "Visual Studio 11 2012 Win64"2015이면 "Visual Studio 12 2015 Win64"입니다. 다음은 실제로 명령 프롬프트에서 친 ① ~ ④의 명령의 모습입니다. 알기 쉽게하기 위해 dlib과 cmake를 모두 바탕 화면에두고있었습니다. ①은 dlib의 examples 폴더로 이동하는 명령 (나의 경우는 바탕 화면에 둔 dlib-18.18 폴더에 있습니다) ②는 examples에서 "build"라는 cmake 용 폴더를 만들 명령, ③ 그 build 폴더로 이동하는 명령입니다. ④를 실행하면 cmake에서 configure와 generate하는 동작이 실행됩니다. cmake를 실행하려면 바탕 화면의 cmake 경로 (다운로드 폴더의 bin 폴더에있는)를 찍을 수 있습니다. 다음과 같이 "Configuring done", "Generating done"라고 나와 Build files ~~라고되어 있으면 OK입니다. 마지막으로 ⑤ 명령을 치면 OK입니다. 다시 말하지만, cmake 경로는 cmake를 둔 위치합니다. 이 명령을 완료하는 데 몇 분 정도 걸립니다. 기본적으로 이것으로 좋은 합니다만, dlib를 빠르게 움직이고 싶은 경우에는 cmake에서 컴파일 할 때 AVX와 SSE4 같은 옵션을 선택해야합니다. AVX의 것이 SSE4보다 빠른 것 같습니다만, 오래된 PC라고 AVX를 지원하지 않는 경우도 있다고합니다. 이 옵션을 지정하고 싶은 경우는 ⑤의 명령 대신 "(cmake 경로) /cmake-gui.exe"라고 쳐 GUI를 사용합니다. AVX와 SSE4 란에 체크 Configure -> Generate 순으로 버튼을 눌러 가면 OK입니다. cmake를 사용한 것은 이상으로 끝에서 dlib의 도입 examples 폴더에있는 샘플 파일을 실행합니다. 다운로드 한 dlib 폴더의 "examples"폴더에 "build"라는 폴더 수 있습니다. (아까 만든 녀석입니다.) 그 안에 "examples.sln"라는 파일 수있을 것입니다. 이것을 Visual Studio에서 엽니 다. 이것을 열면 Examples로 제공되는 대부분의 파일이 프로젝트로 구성되어 있습니다. 이 상태에서 다른 good to go입니다. 우선 F7 키에서 솔루션 파일 (.sln) 전체 빌드합니다. 좀 기다립니다. 이제 드디어 샘플 프로그램을 실행할 수 있습니다. 우선 시험해보고 싶은 프로그램을 선택하십시오. 하나로 결정하면 그 프로젝트 만 수행 할 수있게합니다. 솔루션 쇼 네크 뿌로라 상단의 '솔루션'examples '(85 프로젝트 or 86 프로젝트) "를 오른쪽 클릭하여 속성을 선택하십시오. "싱글 시작 프로젝트 '라는 항목에서 수행 할 프로젝트를 선택하십시오. 이제 또 샘플을 실행합니다. 특히 입력 인수가 필요없는 샘플 프로그램이면 F5 키에서 실행 가능합니다. 이미지 등의 입력이 필요한 프로그램의 경우에는 당해 프로젝트를 오른쪽 클릭하고 "속성"⇒ "구성 속성> 디버그"의 "명령 인자"란에 이미지 파일 이름 등을 입력하여 실행할 수 있습니다. 각각의 샘플 코드 중의 해설을 읽어보십시오. 얼굴 기관 인식 등은 학습 된 데이터가 준비되어 있기 때문에, Web에서 다운로드하여 사용할 수 있습니다 ( http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2 ) 또한 "Webcam_face_pose_ex"라는 Web 카메라 검색된 동영상 속 얼굴을 실시간으로 감지하는 샘플에서는 OpenCV가 필요하므로 cmake에서 OpenCV가 자동으로 참조되지 않는 경우에는 프로젝트 파일이 생성되지 않습니다. OpenCV가없는 경우에는 도입하면 나중에 수동으로 cmake를 사용하여 수행 할 수 있습니다. CMakeList.txt라는 cmake 관련 파일을 조금 만져 줄 필요가 있습니다.

     

    Method of introducing dlib to the Windows / Visual Studio environment

    Hello. 
    Image processing and machine learning today, because it was to experiment with the library "dlib" having a convenient and high-performance features such as facial recognition, I think I'll keep together the way of its introduction as a memorandum. Why so article on how the introduction of the Windows environment there was little, has led I will Noseyo to blog because it is long-awaited. I know my environment, but in Windows 10, we use the Visual Studio 2012. version of dlib has tried the most recent one in 2016 current (dlib 18.18). The following are the steps. First http://dlib.net/ download of dlib from. Please unzip so it can be downloaded in a zip file. Subsequently, in order to trial the dlib, you must compile correctly. So, it is the official recommends that you compile with cmake.http://dlib.net of To Compile How ( Http://Dlib.Net/compile.Html ) to has also been described link ( Https://Cmake.Org/ ) you have to download the cmake from. (Already those who have cmake is no particular need is a new one.) June 2016 that it is currently cmake 3.5.2 is the latest version. In Source distributions without, please download the ZIP for Windows from anyone who Binary distributions. Please put in the appropriate places and unzip After downloading the zip. you can create a build file in the GUI With cmake, but this time you compile by cmake at the command prompt, and conformity with methods that are recommended the official dlib. To Compile How ( Http://Dlib.Net/compile.Html we will follow the steps of). Command prompt (by pressing the Windows key, you come out and hit the "cmd".) Use only hit the command of ① ~ ⑤ above. However, the above does not mean I should strike completely as it is because it omitted the path of the path and dlib of cmake. In particular, if you want to implement a 64bit application in Visual Studio, ④ of the command will be the following. However, note that this ④ also commands for the Visual Studio 2010. If the Visual Studio 2012 "Visual Studio 11 2012 Win64", will be the "Visual Studio 12 2015 Win64" if it is 2015. The following is a state of ① ~ ④ of command struck actually at the command prompt. For the sake of clarity, we've put on the desktop both dlib and cmake. ①, the command to move to the examples folder of dlib (in the case of me there to dlib-18.18 in the folder, which was placed on the desktop), ② is to create a folder for cmake called "build" in the examples command, ③ is the command to move to the build folder. ④ configure in When you run cmake, operations that generate runs. To run the cmake, you need to hit the path of cmake on the desktop (located in the bin folder of the folder where you downloaded). The following as "Configuring done", is OK when I turned I Build files ~~ out I "Generating done". Finally, it is OK by typing the ⑤ command of. Again, the path of cmake is the place to put the cmake. It takes a few minutes to complete this command. Basically I'm good at this, but, if you want to move the dlib at high speed, you need to select the AVX and SSE4 like a option when compiling with cmake. Person of AVX is is fast like than SSE4, but so there is a case that does not correspond to the AVX and an old PC. If you want to specify these options, instead of ⑤ of command, by typing "(path of cmake) /cmake-gui.exe.", You use the GUI. Check the AVX and column of SSE4 Configure - it is OK if we press the button in the order of> Generate. At the end in the above to use cmake, and run the sample files in the introduction examples in the folder of dlib. In the "examples" folder in the folder of the downloaded dlib Are you a folder called "build". (This guy made ​​a little while ago.) You should have a file named in it, "examples.sln". This is open in Visual Studio. When you open this, most of the files that are provided as Examples have been organized as a project. Is another good to go in this state. First, make the solution file (.sln) the entire build with F7 key. You a little wait. Now you can finally sample program is run. Please choose the program that First want to try.Once you have decided on one, so that you can perform only the project. At the top of the solution cane next-Purora the "solutions 'examples' (85 projects or 86 projects)" by right-clicking, please select Properties. The item named "single startup project", please select the project that you want to run. This another sample can run on. If a particular need no sample program input arguments, it can be executed in the F5 key. In the case of the input is necessary programs, such as images, it can be done by right-clicking the project, to enter the image file name, and the like in the "Command Arguments" column of the "Properties" ⇒ "Configuration Properties> Debugging". Please read the commentary in each of the sample code. Because in such as the face organ recognition are prepared is learned data, it can be used by downloading from the Web (Http://Dlib.Net/files/shape_predictor_68_face_landmarks.Dat.Bz2 ) Also, the Web camera as "Webcam_face_pose_ex" because the sample to detect the face in the acquired video in real time required OpenCV, if the OpenCV from cmake is not referenced in the automatic will not be generated by the project file. Be introduced if there is no OpenCV, you can manually run by using the cmake later. There is a need I'll play around a little file on cmake called CMakeList.txt.












































    at the end of line 4, ' ..' should be written.















































    And at the end of the commentary for the introduction of dlib above.
    I'm sorry if there are places that are wrong If.

     

    Posted by uniqueone
    ,
    http://www.noneface.com/2016/03/08/img_retrieval.html

     

     

    MatconvNet

    MatConvNet convolutional neural network tool is a matlab-based open-source package, and offers a variety of pre-trained models. More detailed information on their own google.

    About MatConvNet configuration

    Please refer to

    Or the official website

    pre-train models 选取

    1.imagenet-googlenet-day.The food

    2.imagenet-vgg-m.mat

    3.imagenet-VGG-very deep 16.mat

    Feature Extraction

    Because of the need to use prior to completion of the integration of two features, so features will save all the pictures to the same file, making it easy to use.

    imagenet-vgg-m.mat

    run ./matconvnet-1.0-beta17/matlab/vl_setupnn
    net = load('imagenet-vgg-m.mat');
    addpath('LULC');
    imgFiles = dir('LULC');
    imgNamList = {imgFiles(~[imgFiles.isdir]).name};
    imgNamList = imgNamList';
    numImg = length(imgNamList);
    feat = [];
    for i =1:numImg
       img = imread(imgNamList{i, 1});
    
       if size(img, 3) == 3
           im_ = single(img) ; % note: 255 range
           im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
           im_ = im_ - net.meta.normalization.averageImage ;
           res = vl_simplenn(net, im_) ;
           % viesion: matconvnet-1.0-beta17
           featVec = res(17).x;
           featVec = featVec(:);
           feat = [feat; featVec'];
       else
           im_ = single(repmat(img,[1 1 3])) ; % note: 255 range
           im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
           im_ = im_ - net.meta.normalization.averageImage ;
           res = vl_simplenn(net, im_) ;
           
           % viesion: matconvnet-1.0-beta17
           featVec = res(17).x;
           featVec = featVec(:);
           feat = [feat; featVec'];
       end
    
    end
    resultName = 'D:\img\image-Retrieval\cnn\vgg_m.txt';
    fid = fopen(resultName,'w');
    [r,c] = size(feat);
    for k = 1:r
        for j = 1:c
            fprintf(fid,'%f ',feat(k,j));
        
        end
        fprintf(fid,'\n');
    end
    imagenet-googlenet-day.The food

    run ./matconvnet-1.0-beta17/matlab/vl_setupnn
    modelPath = 'imagenet-googlenet-dag.mat' ;
    net = dagnn.DagNN.loadobj(load(modelPath)) ;
    addpath('LULC');
    imgFiles = dir('LULC');
    imgNamList = {imgFiles(~[imgFiles.isdir]).name};
    imgNamList = imgNamList';
    numImg = length(imgNamList);
    feat = [];
    for i =1:numImg
       img = imread(imgNamList{i, 1});
    
       if size(img, 3) == 3
           im_ = single(img) ; % note: 255 range
           im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
           im_ = im_ - net.meta.normalization.averageImage ;
           net.eval({'data', im_}) ;
           % viesion: matconvnet-1.0-beta17
           featVec = net.vars(152).value;
           featVec = featVec(:);
           feat = [feat; featVec'];
       else
           im_ = single(repmat(img,[1 1 3])) ; % note: 255 range
           im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
           im_ = im_ - net.meta.normalization.averageImage ;
           net.eval({'data', im_}) ;
           % viesion: matconvnet-1.0-beta17
           featVec = net.vars(152).value;
           featVec = featVec(:);
           feat = [feat; featVec'];
       end
    end
    resultName = 'D:\img\image-Retrieval\cnn\googlenet.txt';
    fid = fopen(resultName,'w');
    [r,c] = size(feat);
    for k = 1:r
        for j = 1:c
            fprintf(fid,'%f ',feat(k,j));
        
        end
        fprintf(fid,'\n');
    end
    imagenet-VGG-very deep 16.mat

    run ./matconvnet-1.0-beta17/matlab/vl_setupnn
    net = load('imagenet-vgg-verydeep-16.mat');
    addpath('LULC');
    imgFiles = dir('LULC');
    imgNamList = {imgFiles(~[imgFiles.isdir]).name};
    imgNamList = imgNamList';
    numImg = length(imgNamList);
    feat = [];
    for i =1:numImg
       img = imread(imgNamList{i, 1});
        fprintf('%s is extract cnn.\n',imgNamList{i,1});
       if size(img, 3) == 3
           im_ = single(img) ; % note: 255 range
           im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
           im_ = bsxfun(@minus,im_,net.meta.normalization.averageImage) ;
           res = vl_simplenn(net, im_) ;
           % viesion: matconvnet-1.0-beta17
           featVec = res(33).x;
           featVec = featVec(:);
           feat = [feat; featVec'];
       else
           im_ = single(repmat(img,[1 1 3])) ; % note: 255 range
           im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
           im_ = bsxfun(@minus,im_,net.meta.normalization.averageImage) ;
           res = vl_simplenn(net, im_) ;
           
           % viesion: matconvnet-1.0-beta17
           featVec = res(33).x;
           featVec = featVec(:);
           feat = [feat; featVec'];
       end
    end
    resultName = 'D:\img\image-Retrieval\cnn\vgg_vd.txt';
    fid = fopen(resultName,'w');
    [r,c] = size(feat);
    for k = 1:r
        for j = 1:c
            fprintf(fid,'%f ',feat(k,j));
        
        end
        fprintf(fid,'\n');
    end

    Retrieval

    #coding:utf8
    import os
    import numpy as np
    import re
    from sklearn import preprocessing
    
    def load_features():
    
    	fobj = open('vgg_vd.txt')
    	im_features = []
    	for line in fobj:
    		line = line.rstrip()
    		line = line.split()	
    		
    		im_feature = []
    		for l in line:
    			im_feature.append(float(l))
    		
    		im_features.append(im_feature)
    
    	im_features = np.array(im_features)
    	im_features = preprocessing.normalize(im_features, norm='l2')
    	return im_features
    
    def match_all(query_feature,im_features):
    	score = np.dot(query_feature, im_features.T)
    	rank_ID = np.argsort(-score)
    	return rank_ID
    
    def get_img_id():
    
    	filename = "AllimgName.txt" # 所有图片文件名的txt文件
    	fobj = open(filename)
    	AllimgName = []
    	for line in fobj:
    		line = line.rstrip()
    		AllimgName.append(line)
    	return AllimgName
    
    if __name__ == '__main__':
    	path = 'result'
    	AllimgName = get_img_id()
    	feat = load_features()
    	im_features = feat
    	a = 0
    	for im in feat:
    		rank_ID = match_all(im,im_features)
    		name = AllimgName[a]
    		real_name = re.sub(r'.tif','.txt',name)
    		id_name = re.sub(r'.tif','_id.txt',name)
    
    		real_name = path+'\\'+ 'vgg_vd\\'+'name' +'\\'+ real_name
    		id_name = path +'\\'+ 'vgg_vd\\'+'id' +'\\'+ id_name
    		fobj1 = open(real_name,"w")
    		fobj2 = open(id_name,"w")
    
    		for i in rank_ID:
    			 fobj1.write(AllimgName[i]+'\n')
    			 fobj2.write(str(i)+' ')
    		fobj1.close()
    		fobj2.close()
    		a += 1

    Since then we need to use Graph integration, and Graph integration need to use the photo id, so the way the id is also preserved. About retrieve additional models directly modify the model and the path to save the final result loaded ok.

    result

    Merge

    Based on previous fusion code, perform Graph and adaptive integration.

    Fine tuning

    1. Build your own data imdb.mat

    In matconvnet, the official specified a file format. However, in the examples in matconvnet, I do not understand how it is generated imdb.mat file. After google to a related paper , we found a method of generating.

    function imdb =setup_data(averageImage)
    %code for Computer Vision, Georgia Tech by James Hays
    
    %This path is assumed to contain 'test' and 'train' which each contain 15
    %subdirectories. The train folder has 100 samples of each category and the
    %test has an arbitrary amount of each category. This is the exact data and
    %train/test split used in Project 4.
    SceneJPGsPath = 'data/LULC/';
    
    num_train_per_category = 80;
    num_test_per_category  = 20; %can be up to 110
    total_images = 21*num_train_per_category + 21 * num_test_per_category;
    
    image_size = [224 224]; %downsampling data for speed and because it hurts
    % accuracy surprisingly little
    
    imdb.images.data   = zeros(image_size(1), image_size(2), 1, total_images, 'single');
    imdb.images.labels = zeros(1, total_images, 'single');
    imdb.images.set    = zeros(1, total_images, 'uint8');
    image_counter = 1;
    
    categories = {'agricultural', 'airplane', 'baseballdiamond', 'beach', ...
                  'buildings', 'chaparral', 'denseresidential', ...
                  'forest', 'freeway', 'golfcourse', 'harbor', ...
                  'intersection', 'mediumresidential', 'mobilehomepark', 'overpass',...
                  'parkinglot','river','runway','sparseresidential','storagetanks','tenniscourt'};
              
    sets = {'train', 'test'};
    
    fprintf('Loading %d train and %d test images from each category\n', ...
              num_train_per_category, num_test_per_category)
    fprintf('Each image will be resized to %d by %d\n', image_size(1),image_size(2));
    
    %Read each image and resize it to 224x224
    for set = 1:length(sets)
        for category = 1:length(categories)
            cur_path = fullfile( SceneJPGsPath, sets{set}, categories{category});
            cur_images = dir( fullfile( cur_path,  '*.tif') );
            
            if(set == 1)
                fprintf('Taking %d out of %d images in %s\n', num_train_per_category, length(cur_images), cur_path);
                cur_images = cur_images(1:num_train_per_category);
            elseif(set == 2)
                fprintf('Taking %d out of %d images in %s\n', num_test_per_category, length(cur_images), cur_path);
                cur_images = cur_images(1:num_test_per_category);
            end
    
            for i = 1:length(cur_images)
    
                cur_image = imread(fullfile(cur_path, cur_images(i).name));
                cur_image = single(cur_image);
                cur_image = imresize(cur_image, image_size);
                
                %cur_image = bsxfun(@minus,cur_image,averageImage) ;
                cur_image = cur_image - averageImage;
                
                if(size(cur_image,3) > 1)
                    fprintf('color image found %s\n', fullfile(cur_path, cur_images(i).name));
                    cur_image = rgb2gray(cur_image);
                    
                end
               
                
                % Stack images into a large 224 x 224 x 1 x total_images matrix
                % images.data
                imdb.images.data(:,:,1,image_counter) = cur_image; 
                
                imdb.images.labels(  1,image_counter) = category;
                imdb.images.set(     1,image_counter) = set; %1 for train, 2 for test (val?)
                
                image_counter = image_counter + 1;
            end
        end
    end

    The function returns imdb save ok.

    Warning 下面的微调代码存在问题!!!

    2.fine tune

    With regard to the pre-trained models were fine tune, currently only completed imagenet-vgg-verydeep-16.mat and imagenet-vgg-m.mat two models of fine-tuning, this model corresponds googlenet, then any problem.

    function [net,info] = fine_tune()
    run ./matconvnet-1.0-beta17/matlab/vl_setupnn;
    
    imdb = load('imdb.mat');
    net = load('imagenet-vgg-verydeep-16.mat');
    opts.train.expDir = fullfile('data','vd0.005') ;
    
    net.layers = net.layers(1:end-2);
    net.layers{end+1} = struct('type', 'conv', ...
    'weights', , ...
    'learningRate', [0.005,0.002], ...
    'stride', [1 1], ...
    'pad', [0 0 0 0]) ;
    
    opts.train.batchSize = 20 ;
    opts.train.learningRate = logspace(-4, -5.5, 300) ;
    opts.trian.numEpochs = numel(opts.train.learningRate) ;
    opts.train.continue = true ;
    
    net.layers{end+1} = struct('type', 'softmaxloss') ;
        
    [net, info] = cnn_train(net, imdb, @getBatch, ...
        opts.train,...
        'val', find(imdb.images.set == 2)) ;
    save('fine_tune.mat','-struct', 'net')
    end
    
    function [im, labels] = getBatch(imdb, batch)
    %getBatch is called by cnn_train.
    im = imdb.images.data(:,:,:,batch) ;
    
    labels = imdb.images.labels(1,batch) ;
    end

    More fine tune information please refer to

    result

    Relatively speaking, the result of fine-tuning to enhance the rate did not produce a good result adaptive fusion.

    to sum up

    About two fusion

    My understanding is that the fusion of the two methods, that the result of this adaptive fusion method is more suitable for the calculation of the standard mAP fusion, the final results from the point of view is the same.

    In Graph fusion, the presence of the most deadly thing is, in the integration process, the need for the fusion of two or more results is calculated once a common sub-graph, then looking at the process, not necessarily include all of the pictures (2100 pictures) sort (due mAP is the picture sort dispersed throughout the relevant search results, about mAP refer to ). This will to some extent limit its mAP results.

    after that

    For image retrieval this one do about it, and he sent a model trimming on googlenet not completed and has been submitted to an issues on github, it has not been restored.

    Once this is done I can use them to do something?

    I think they have spare time to do a little project: submit a photo and tell you what the image content inside Yes.
    Related knowledge:

    Estimate must first obtain a certain amount of good pictures already marked, such as crawling enough data from wikipedia or Baidu Encyclopedia, and then image feature extraction data to construct its own database.

    Then also free of these written code review and rewrite the current write readable code is still very poor, can not read from time to time to write their own code.

    EOF

    'Deep Learning' 카테고리의 다른 글

    Free Deep Learning Books  (0) 2016.11.28
    Keras Tutorials  (0) 2016.11.11
    Deep Learning Resources  (1) 2016.09.08
    How to use the network trained using cnn_mnist example in MatConvNet?  (0) 2016.09.06
    How to Start Learning Deep Learning  (0) 2016.08.24
    Posted by uniqueone
    ,