OpenCV Multi view - eiichiromomma/CVMLAB GitHub Wiki
(OpenCV) Multi-view
C++ APIではROIをReleaseする必要が無いので,ROIを複数設定することで1つのウィンドウに結果を複数表示するのが簡単になった。
- 作りたいマルチビュー画面の大きさのMatを作成(例では原画像の1/2のものを2x3で作成)
- 各々の位置にROI(実体はMat)を設定
- ROIへ画像をコピー(例ではResizeの出力先としているのでコピー不要)
大きめに作成して,数値を書き込むスペースのROIも確保すれば,より応用範囲が広がる。
OpenCV Skeletonizationを使った処理で,filter2DをOpenMPによって並列処理させている。
/*
* Kasvand.cpp
*
* Created on: 2011/03/03
* Author: Eiichiro Momma
*/
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include <iostream>
#ifdef _OPENMP
#include <omp.h>
#endif
using namespace cv;
int main(void)
{
#ifdef _OPENMP
std::cout<<"The number of processors is "<<omp_get_num_procs()<<std::endl;
omp_set_num_threads(4);
#endif
float Smax=0;
//Kasvandの反復型線検出オペレータ
float L0[]={
-1,-1,-1,-1,-1,
0, 0, 0, 0, 0,
2, 2, 2, 2, 2,
0, 0, 0, 0, 0,
-1,-1,-1,-1,-1
};
float L45[]={
0,-1,-1, 0, 2,
-1,-1, 0, 2, 0,
-1, 0, 2, 0,-1,
0, 2, 0,-1,-1,
2, 0,-1,-1, 0
};
float L90[]={
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1
};
float L135[]={
2, 0,-1,-1, 0,
0, 2, 0,-1,-1,
-1, 0, 2, 0,-1,
-1,-1, 0, 2, 0,
0,-1,-1, 0, 2
};
VideoCapture cap;
Mat frame, src;
std::vector<Mat> planes;
cap.open(0);
if (!cap.isOpened())
{
std::cout << "Cap Failed" << std::endl;
return 1;
}
cap >> frame;
split(frame, planes);
src = planes[2];
Mat distsrc(src.rows, src.cols, CV_32FC1);
Mat S00 = distsrc.clone();
Mat S45 = distsrc.clone();
Mat S90 = distsrc.clone();
Mat S135 = distsrc.clone();
Mat out = distsrc.clone();
//canvas
Mat fsrc = distsrc.clone();
Mat canvas(src.rows*2/2, src.cols*3/2, CV_32FC1);
//画像を割り振るROIの設定
std::vector<Mat> vroi;
vroi.push_back(canvas(Rect(0,0,src.cols/2, src.rows/2)));
vroi.push_back(canvas(Rect((src.cols/2)*1, (src.rows/2)*0, src.cols/2, src.rows/2)));
vroi.push_back(canvas(Rect((src.cols/2)*2, (src.rows/2)*0, src.cols/2, src.rows/2)));
vroi.push_back(canvas(Rect((src.cols/2)*0, (src.rows/2)*1, src.cols/2, src.rows/2)));
vroi.push_back(canvas(Rect((src.cols/2)*1, (src.rows/2)*1, src.cols/2, src.rows/2)));
vroi.push_back(canvas(Rect((src.cols/2)*2, (src.rows/2)*1, src.cols/2, src.rows/2)));
//kernelの作成
const Mat kern00 = Mat(5, 5, CV_32FC1, L0).clone();
const Mat kern45 = Mat(5, 5, CV_32FC1, L45).clone();
const Mat kern90 = Mat(5, 5, CV_32FC1, L90).clone();
const Mat kern135 = Mat(5, 5, CV_32FC1, L135).clone();
namedWindow("canvas", CV_WINDOW_AUTOSIZE);
int key = 0;
while(key != 27)
{
cap >> frame;
split(frame, planes);
//他の処理に使いたい場合はframeやplanesをいじる
//canvasはCV_32Fの1チャネルになっているので注意
threshold(planes[2], src, 100, 255, CV_THRESH_BINARY);
//距離変換
distanceTransform(src, distsrc, CV_DIST_L2, 5);
//フィルタ処理
#ifdef _OPENMP
#pragma omp parallel
#pragma omp sections
{
#pragma omp section
{
filter2D(distsrc, S00, CV_32FC1, kern00);
}
#pragma omp section
{
filter2D(distsrc, S45, CV_32FC1, kern45);
}
#pragma omp section
{
filter2D(distsrc, S90, CV_32FC1, kern90);
}
#pragma omp section
{
filter2D(distsrc, S135, CV_32FC1, kern135);
}
}
#else
filter2D(distsrc, S00, CV_32FC1, kern00);
filter2D(distsrc, S45, CV_32FC1, kern45);
filter2D(distsrc, S90, CV_32FC1, kern90);
filter2D(distsrc, S135, CV_32FC1, kern135);
#endif
//
//Smax = MAX(S00,S45,S90,S135)
// / Smax, Smax >= 0
// g = |
// \ 0 , others
//
for (int y=0; y < out.rows; y++)
{
for (int x=0; x< out.cols; x++)
{
float tmp1 = (S00.at<float>(y, x) > S45.at<float>(y, x) )? S00.at<float>(y, x): S45.at<float>(y, x);
float tmp2 = (S90.at<float>(y, x) > S135.at<float>(y, x) )? S90.at<float>(y, x): S135.at<float>(y, x);
Smax = (tmp1 > tmp2)? tmp1: tmp2;
out.at<float>(y, x) = (Smax > 0)? Smax: 0.0;
}
}
threshold(out, out, 7, 1, CV_THRESH_BINARY);
src.convertTo(fsrc, CV_32FC1, 1.0/255, 0);
resize(fsrc, vroi[0], vroi[0].size(), 0, 0, INTER_LINEAR);
resize(S00, vroi[1], vroi[1].size(), 0, 0, INTER_LINEAR);
resize(S45, vroi[2], vroi[2].size(), 0, 0, INTER_LINEAR);
resize(out, vroi[3], vroi[3].size(), 0, 0, INTER_LINEAR);
resize(S90, vroi[4], vroi[4].size(), 0, 0, INTER_LINEAR);
resize(S135, vroi[5], vroi[5].size(), 0, 0, INTER_LINEAR);
imshow("canvas", canvas);
key = waitKey(33);
}
return 0;
}
最後は適当
import cv2
import numpy as np
L0 = np.array(
[-1,-1,-1,-1,-1,
0, 0, 0, 0, 0,
2, 2, 2, 2, 2,
0, 0, 0, 0, 0,
-1,-1,-1,-1,-1], np.float32).reshape(5,5)
L45 = np.array(
[0,-1,-1, 0, 2,
-1,-1, 0, 2, 0,
-1, 0, 2, 0,-1,
0, 2, 0,-1,-1,
2, 0,-1,-1, 0], np.float32).reshape(5,5)
L90 = np.array(
[-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1], np.float32).reshape(5,5)
L135 = np.array(
[ 2, 0,-1,-1, 0,
0, 2, 0,-1,-1,
-1, 0, 2, 0,-1,
-1,-1, 0, 2, 0,
0,-1,-1, 0, 2], np.float32).reshape(5,5)
img1 = cv2.imread('sandbox/lena.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('Src',img1)
th, img2 = cv2.threshold(img1, 128, 255, cv2.THRESH_BINARY)
dimage = cv2.distanceTransform(img2, cv2.DIST_L2,5)
dimage = dimage/dimage.max()
cv2.imshow('dist',dimage)
R00 = cv2.filter2D(dimage, cv2.CV_32F, L0)
R45 = cv2.filter2D(dimage, cv2.CV_32F, L45)
R90 = cv2.filter2D(dimage, cv2.CV_32F, L90)
R135= cv2.filter2D(dimage, cv2.CV_32F, L135)
Racc = R00+R45+R90+R135
cv2.imshow('Result', Racc/Racc.max())
#MultiView
canvas = np.zeros([x*2 for x in img1.shape], dtype=np.float32 )
canvas[0:int(canvas.shape[0]/2), 0:int(canvas.shape[1]/2)] = img1/255.0
canvas[0:int(canvas.shape[0]/2), int(canvas.shape[1]/2):] = img2/255.0
canvas[int(canvas.shape[0]/2):, 0:int(canvas.shape[1]/2)] = dimage
canvas[int(canvas.shape[0]/2):, int(canvas.shape[1]/2):] = Racc/Racc.max()
cv2.imshow('multi',canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()
特にやることは変わらない
import cv2
import numpy as np
L0 = np.array(
[-1,-1,-1,-1,-1,
0, 0, 0, 0, 0,
2, 2, 2, 2, 2,
0, 0, 0, 0, 0,
-1,-1,-1,-1,-1], np.float32).reshape(5,5)
L45 = np.array(
[0,-1,-1, 0, 2,
-1,-1, 0, 2, 0,
-1, 0, 2, 0,-1,
0, 2, 0,-1,-1,
2, 0,-1,-1, 0], np.float32).reshape(5,5)
L90 = np.array(
[-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1,
-1, 0, 2, 0,-1], np.float32).reshape(5,5)
L135 = np.array(
[ 2, 0,-1,-1, 0,
0, 2, 0,-1,-1,
-1, 0, 2, 0,-1,
-1,-1, 0, 2, 0,
0,-1,-1, 0, 2], np.float32).reshape(5,5)
cap = cv2.VideoCapture(0)
key = 0
while key!=27:
t, img1 = cap.read()
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
th, img2 = cv2.threshold(img1, 128, 255, cv2.THRESH_BINARY)
dimage = cv2.distanceTransform(img2, cv2.DIST_L2,5)
dimage = dimage/dimage.max()
R00 = cv2.filter2D(dimage, cv2.CV_32F, L0)
R45 = cv2.filter2D(dimage, cv2.CV_32F, L45)
R90 = cv2.filter2D(dimage, cv2.CV_32F, L90)
R135= cv2.filter2D(dimage, cv2.CV_32F, L135)
Racc = R00+R45+R90+R135
#MultiView
canvas = np.zeros([x*2 for x in img1.shape], dtype=np.float32 )
canvas[0:int(canvas.shape[0]/2), 0:int(canvas.shape[1]/2)] = img1/255.0
canvas[0:int(canvas.shape[0]/2), int(canvas.shape[1]/2):] = img2/255.0
canvas[int(canvas.shape[0]/2):, 0:int(canvas.shape[1]/2)] = dimage
canvas[int(canvas.shape[0]/2):, int(canvas.shape[1]/2):] = Racc/Racc.max()
cv2.imshow('multi',canvas)
key = cv2.waitKey(10)
cv2.destroyAllWindows()