Merge pull request #18940 from vpisarev:3d_light
commit
65b0383059
232 changed files with 7670 additions and 7613 deletions
@ -1,4 +1,4 @@ |
||||
file(GLOB SRCS *.cpp) |
||||
ocv_add_application(opencv_createsamples |
||||
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d opencv_videoio |
||||
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_3d opencv_features2d opencv_videoio |
||||
SRCS ${SRCS}) |
||||
|
@ -1,5 +1,5 @@ |
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Woverloaded-virtual -Winconsistent-missing-override -Wsuggest-override) |
||||
file(GLOB SRCS *.cpp) |
||||
ocv_add_application(opencv_traincascade |
||||
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d |
||||
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_3d opencv_features2d |
||||
SRCS ${SRCS}) |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,240 @@ |
||||
// |
||||
// Calib3dTest.swift |
||||
// |
||||
// Created by Giles Payne on 2020/05/26. |
||||
// |
||||
|
||||
import XCTest |
||||
import OpenCV |
||||
|
||||
class Cv3dTest: OpenCVTestCase { |
||||
|
||||
var size = Size() |
||||
|
||||
override func setUp() { |
||||
super.setUp() |
||||
size = Size(width: 3, height: 3) |
||||
} |
||||
|
||||
override func tearDown() { |
||||
super.tearDown() |
||||
} |
||||
|
||||
func testComposeRTMatMatMatMatMatMat() throws { |
||||
let rvec1 = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try rvec1.put(row: 0, col: 0, data: [0.5302828, 0.19925919, 0.40105945] as [Float]) |
||||
let tvec1 = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try tvec1.put(row: 0, col: 0, data: [0.81438506, 0.43713298, 0.2487897] as [Float]) |
||||
let rvec2 = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try rvec2.put(row: 0, col: 0, data: [0.77310503, 0.76209372, 0.30779448] as [Float]) |
||||
let tvec2 = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try tvec2.put(row: 0, col: 0, data: [0.70243168, 0.4784472, 0.79219002] as [Float]) |
||||
|
||||
let rvec3 = Mat() |
||||
let tvec3 = Mat() |
||||
|
||||
let outRvec = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try outRvec.put(row: 0, col: 0, data: [1.418641, 0.88665926, 0.56020796]) |
||||
let outTvec = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
try outTvec.put(row: 0, col: 0, data: [1.4560841, 1.0680628, 0.81598103]) |
||||
|
||||
Cv3d.composeRT(rvec1: rvec1, tvec1: tvec1, rvec2: rvec2, tvec2: tvec2, rvec3: rvec3, tvec3: tvec3) |
||||
|
||||
try assertMatEqual(outRvec, rvec3, OpenCVTestCase.EPS) |
||||
try assertMatEqual(outTvec, tvec3, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testFindHomographyListOfPointListOfPoint() throws { |
||||
let NUM:Int32 = 20 |
||||
|
||||
let originalPoints = MatOfPoint2f() |
||||
originalPoints.alloc(NUM) |
||||
let transformedPoints = MatOfPoint2f() |
||||
transformedPoints.alloc(NUM) |
||||
|
||||
for i:Int32 in 0..<NUM { |
||||
let x:Float = Float.random(in: -50...50) |
||||
let y:Float = Float.random(in: -50...50) |
||||
try originalPoints.put(row:i, col:0, data:[x, y]) |
||||
try transformedPoints.put(row:i, col:0, data:[y, x]) |
||||
} |
||||
|
||||
let hmg = Cv3d.findHomography(srcPoints: originalPoints, dstPoints: transformedPoints) |
||||
|
||||
truth = Mat(rows: 3, cols: 3, type: CvType.CV_64F) |
||||
try truth!.put(row:0, col:0, data:[0, 1, 0, 1, 0, 0, 0, 0, 1] as [Double]) |
||||
try assertMatEqual(truth!, hmg, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testRodriguesMatMat() throws { |
||||
let r = Mat(rows: 3, cols: 1, type: CvType.CV_32F) |
||||
let R = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
|
||||
try r.put(row:0, col:0, data:[.pi, 0, 0] as [Float]) |
||||
|
||||
Cv3d.Rodrigues(src: r, dst: R) |
||||
|
||||
truth = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
try truth!.put(row:0, col:0, data:[1, 0, 0, 0, -1, 0, 0, 0, -1] as [Float]) |
||||
try assertMatEqual(truth!, R, OpenCVTestCase.EPS) |
||||
|
||||
let r2 = Mat() |
||||
Cv3d.Rodrigues(src: R, dst: r2) |
||||
|
||||
try assertMatEqual(r, r2, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testSolvePnPListOfPoint3ListOfPointMatMatMatMat() throws { |
||||
let intrinsics = Mat.eye(rows: 3, cols: 3, type: CvType.CV_64F) |
||||
try intrinsics.put(row: 0, col: 0, data: [400] as [Double]) |
||||
try intrinsics.put(row: 1, col: 1, data: [400] as [Double]) |
||||
try intrinsics.put(row: 0, col: 2, data: [640 / 2] as [Double]) |
||||
try intrinsics.put(row: 1, col: 2, data: [480 / 2] as [Double]) |
||||
|
||||
let minPnpPointsNum: Int32 = 4 |
||||
|
||||
let points3d = MatOfPoint3f() |
||||
points3d.alloc(minPnpPointsNum) |
||||
let points2d = MatOfPoint2f() |
||||
points2d.alloc(minPnpPointsNum) |
||||
|
||||
for i in 0..<minPnpPointsNum { |
||||
let x = Float.random(in: -50...50) |
||||
let y = Float.random(in: -50...50) |
||||
try points2d.put(row: i, col: 0, data: [x, y]) //add(Point(x, y)) |
||||
try points3d.put(row: i, col: 0, data: [0, y, x]) // add(Point3(0, y, x)) |
||||
} |
||||
|
||||
let rvec = Mat() |
||||
let tvec = Mat() |
||||
Cv3d.solvePnP(objectPoints: points3d, imagePoints: points2d, cameraMatrix: intrinsics, distCoeffs: MatOfDouble(), rvec: rvec, tvec: tvec) |
||||
|
||||
let truth_rvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F) |
||||
try truth_rvec.put(row: 0, col: 0, data: [0, .pi / 2, 0] as [Double]) |
||||
|
||||
let truth_tvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F) |
||||
try truth_tvec.put(row: 0, col: 0, data: [-320, -240, 400] as [Double]) |
||||
|
||||
try assertMatEqual(truth_rvec, rvec, OpenCVTestCase.EPS) |
||||
try assertMatEqual(truth_tvec, tvec, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testComputeCorrespondEpilines() throws { |
||||
let fundamental = Mat(rows: 3, cols: 3, type: CvType.CV_64F) |
||||
try fundamental.put(row: 0, col: 0, data: [0, -0.577, 0.288, 0.577, 0, 0.288, -0.288, -0.288, 0]) |
||||
let left = MatOfPoint2f() |
||||
left.alloc(1) |
||||
try left.put(row: 0, col: 0, data: [2, 3] as [Float]) //add(Point(x, y)) |
||||
let lines = Mat() |
||||
let truth = Mat(rows: 1, cols: 1, type: CvType.CV_32FC3) |
||||
try truth.put(row: 0, col: 0, data: [-0.70735186, 0.70686162, -0.70588124]) |
||||
Cv3d.computeCorrespondEpilines(points: left, whichImage: 1, F: fundamental, lines: lines) |
||||
try assertMatEqual(truth, lines, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testSolvePnPGeneric_regression_16040() throws { |
||||
let intrinsics = Mat.eye(rows: 3, cols: 3, type: CvType.CV_64F) |
||||
try intrinsics.put(row: 0, col: 0, data: [400] as [Double]) |
||||
try intrinsics.put(row: 1, col: 1, data: [400] as [Double]) |
||||
try intrinsics.put(row: 0, col: 2, data: [640 / 2] as [Double]) |
||||
try intrinsics.put(row: 1, col: 2, data: [480 / 2] as [Double]) |
||||
|
||||
let minPnpPointsNum: Int32 = 4 |
||||
|
||||
let points3d = MatOfPoint3f() |
||||
points3d.alloc(minPnpPointsNum) |
||||
let points2d = MatOfPoint2f() |
||||
points2d.alloc(minPnpPointsNum) |
||||
|
||||
for i in 0..<minPnpPointsNum { |
||||
let x = Float.random(in: -50...50) |
||||
let y = Float.random(in: -50...50) |
||||
try points2d.put(row: i, col: 0, data: [x, y]) //add(Point(x, y)) |
||||
try points3d.put(row: i, col: 0, data: [0, y, x]) // add(Point3(0, y, x)) |
||||
} |
||||
|
||||
var rvecs = [Mat]() |
||||
var tvecs = [Mat]() |
||||
|
||||
let rvec = Mat() |
||||
let tvec = Mat() |
||||
|
||||
let reprojectionError = Mat(rows: 2, cols: 1, type: CvType.CV_64FC1) |
||||
|
||||
Cv3d.solvePnPGeneric(objectPoints: points3d, imagePoints: points2d, cameraMatrix: intrinsics, distCoeffs: MatOfDouble(), rvecs: &rvecs, tvecs: &tvecs, useExtrinsicGuess: false, flags: .SOLVEPNP_IPPE, rvec: rvec, tvec: tvec, reprojectionError: reprojectionError) |
||||
|
||||
let truth_rvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F) |
||||
try truth_rvec.put(row: 0, col: 0, data: [0, .pi / 2, 0] as [Double]) |
||||
|
||||
let truth_tvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F) |
||||
try truth_tvec.put(row: 0, col: 0, data: [-320, -240, 400] as [Double]) |
||||
|
||||
try assertMatEqual(truth_rvec, rvecs[0], 10 * OpenCVTestCase.EPS) |
||||
try assertMatEqual(truth_tvec, tvecs[0], 1000 * OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testGetDefaultNewCameraMatrixMat() { |
||||
let mtx = Cv3d.getDefaultNewCameraMatrix(cameraMatrix: gray0) |
||||
|
||||
XCTAssertFalse(mtx.empty()) |
||||
XCTAssertEqual(0, Core.countNonZero(src: mtx)) |
||||
} |
||||
|
||||
func testGetDefaultNewCameraMatrixMatSizeBoolean() { |
||||
let mtx = Cv3d.getDefaultNewCameraMatrix(cameraMatrix: gray0, imgsize: size, centerPrincipalPoint: true) |
||||
|
||||
XCTAssertFalse(mtx.empty()) |
||||
XCTAssertFalse(0 == Core.countNonZero(src: mtx)) |
||||
// TODO_: write better test |
||||
} |
||||
|
||||
func testUndistortMatMatMatMat() throws { |
||||
let src = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(3)) |
||||
let cameraMatrix = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
try cameraMatrix.put(row: 0, col: 0, data: [1, 0, 1] as [Float]) |
||||
try cameraMatrix.put(row: 1, col: 0, data: [0, 1, 2] as [Float]) |
||||
try cameraMatrix.put(row: 2, col: 0, data: [0, 0, 1] as [Float]) |
||||
|
||||
let distCoeffs = Mat(rows: 1, cols: 4, type: CvType.CV_32F) |
||||
try distCoeffs.put(row: 0, col: 0, data: [1, 3, 2, 4] as [Float]) |
||||
|
||||
Cv3d.undistort(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs) |
||||
|
||||
truth = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
try truth!.put(row: 0, col: 0, data: [0, 0, 0] as [Float]) |
||||
try truth!.put(row: 1, col: 0, data: [0, 0, 0] as [Float]) |
||||
try truth!.put(row: 2, col: 0, data: [0, 3, 0] as [Float]) |
||||
|
||||
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
func testUndistortMatMatMatMatMat() throws { |
||||
let src = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(3)) |
||||
let cameraMatrix = Mat(rows: 3, cols: 3, type: CvType.CV_32F) |
||||
try cameraMatrix.put(row: 0, col: 0, data: [1, 0, 1] as [Float]) |
||||
try cameraMatrix.put(row: 1, col: 0, data: [0, 1, 2] as [Float]) |
||||
try cameraMatrix.put(row: 2, col: 0, data: [0, 0, 1] as [Float]) |
||||
|
||||
let distCoeffs = Mat(rows: 1, cols: 4, type: CvType.CV_32F) |
||||
try distCoeffs.put(row: 0, col: 0, data: [2, 1, 4, 5] as [Float]) |
||||
|
||||
let newCameraMatrix = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(1)) |
||||
|
||||
Cv3d.undistort(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs, newCameraMatrix: newCameraMatrix) |
||||
|
||||
truth = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(3)) |
||||
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS) |
||||
} |
||||
|
||||
//undistortPoints(List<Point> src, List<Point> dst, Mat cameraMatrix, Mat distCoeffs) |
||||
func testUndistortPointsListOfPointListOfPointMatMat() { |
||||
let src = MatOfPoint2f(array: [Point2f(x: 1, y: 2), Point2f(x: 3, y: 4), Point2f(x: -1, y: -1)]) |
||||
let dst = MatOfPoint2f() |
||||
let cameraMatrix = Mat.eye(rows: 3, cols: 3, type: CvType.CV_64FC1) |
||||
let distCoeffs = Mat(rows: 8, cols: 1, type: CvType.CV_64FC1, scalar: Scalar(0)) |
||||
|
||||
Cv3d.undistortPoints(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs) |
||||
|
||||
XCTAssertEqual(src.toArray(), dst.toArray()) |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,12 @@ |
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include <iostream> |
||||
#include "precomp.hpp" |
||||
#include "epnp.h" |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace cv { |
||||
|
||||
epnp::epnp(const Mat& cameraMatrix, const Mat& opoints, const Mat& ipoints) |
||||
{ |
@ -1,11 +1,14 @@ |
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#ifndef epnp_h |
||||
#define epnp_h |
||||
|
||||
#include "precomp.hpp" |
||||
#include "opencv2/core/core_c.h" |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace cv { |
||||
|
||||
class epnp { |
||||
public: |
@ -0,0 +1,143 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
#ifndef __OPENCV_PRECOMP_H__ |
||||
#define __OPENCV_PRECOMP_H__ |
||||
|
||||
#include "opencv2/core/utility.hpp" |
||||
|
||||
#include "opencv2/core/private.hpp" |
||||
|
||||
#include "opencv2/3d.hpp" |
||||
#include "opencv2/imgproc.hpp" |
||||
#include "opencv2/features2d.hpp" |
||||
|
||||
#include "opencv2/core/ocl.hpp" |
||||
|
||||
#define GET_OPTIMIZED(func) (func) |
||||
|
||||
|
||||
namespace cv { |
||||
|
||||
/**
|
||||
* Compute the number of iterations given the confidence, outlier ratio, number |
||||
* of model points and the maximum iteration number. |
||||
* |
||||
* @param p confidence value |
||||
* @param ep outlier ratio |
||||
* @param modelPoints number of model points required for estimation |
||||
* @param maxIters maximum number of iterations |
||||
* @return |
||||
* \f[ |
||||
* \frac{\ln(1-p)}{\ln\left(1-(1-ep)^\mathrm{modelPoints}\right)} |
||||
* \f] |
||||
* |
||||
* If the computed number of iterations is larger than maxIters, then maxIters is returned. |
||||
*/ |
||||
int RANSACUpdateNumIters( double p, double ep, int modelPoints, int maxIters ); |
||||
|
||||
class CV_EXPORTS PointSetRegistrator : public Algorithm |
||||
{ |
||||
public: |
||||
class CV_EXPORTS Callback |
||||
{ |
||||
public: |
||||
virtual ~Callback() {} |
||||
virtual int runKernel(InputArray m1, InputArray m2, OutputArray model) const = 0; |
||||
virtual void computeError(InputArray m1, InputArray m2, InputArray model, OutputArray err) const = 0; |
||||
virtual bool checkSubset(InputArray, InputArray, int) const { return true; } |
||||
}; |
||||
|
||||
virtual void setCallback(const Ptr<PointSetRegistrator::Callback>& cb) = 0; |
||||
virtual bool run(InputArray m1, InputArray m2, OutputArray model, OutputArray mask) const = 0; |
||||
}; |
||||
|
||||
CV_EXPORTS Ptr<PointSetRegistrator> createRANSACPointSetRegistrator(const Ptr<PointSetRegistrator::Callback>& cb, |
||||
int modelPoints, double threshold, |
||||
double confidence=0.99, int maxIters=1000 ); |
||||
|
||||
CV_EXPORTS Ptr<PointSetRegistrator> createLMeDSPointSetRegistrator(const Ptr<PointSetRegistrator::Callback>& cb, |
||||
int modelPoints, double confidence=0.99, int maxIters=1000 ); |
||||
|
||||
template<typename T> inline int compressElems( T* ptr, const uchar* mask, int mstep, int count ) |
||||
{ |
||||
int i, j; |
||||
for( i = j = 0; i < count; i++ ) |
||||
if( mask[i*mstep] ) |
||||
{ |
||||
if( i > j ) |
||||
ptr[j] = ptr[i]; |
||||
j++; |
||||
} |
||||
return j; |
||||
} |
||||
|
||||
static inline bool haveCollinearPoints( const Mat& m, int count ) |
||||
{ |
||||
int j, k, i = count-1; |
||||
const Point2f* ptr = m.ptr<Point2f>(); |
||||
|
||||
// check that the i-th selected point does not belong
|
||||
// to a line connecting some previously selected points
|
||||
// also checks that points are not too close to each other
|
||||
for( j = 0; j < i; j++ ) |
||||
{ |
||||
double dx1 = ptr[j].x - ptr[i].x; |
||||
double dy1 = ptr[j].y - ptr[i].y; |
||||
for( k = 0; k < j; k++ ) |
||||
{ |
||||
double dx2 = ptr[k].x - ptr[i].x; |
||||
double dy2 = ptr[k].y - ptr[i].y; |
||||
if( fabs(dx2*dy1 - dy2*dx1) <= FLT_EPSILON*(fabs(dx1) + fabs(dy1) + fabs(dx2) + fabs(dy2))) |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void findExtrinsicCameraParams2( const Mat& objectPoints, |
||||
const Mat& imagePoints, const Mat& A, |
||||
const Mat& distCoeffs, Mat& rvec, Mat& tvec, |
||||
int useExtrinsicGuess ); |
||||
|
||||
} // namespace cv
|
||||
|
||||
#endif |
@ -0,0 +1,9 @@ |
||||
set(the_description "Camera Calibration and 3D Reconstruction") |
||||
|
||||
set(debug_modules "") |
||||
if(DEBUG_opencv_calib) |
||||
list(APPEND debug_modules opencv_highgui) |
||||
endif() |
||||
ocv_define_module(calib opencv_imgproc opencv_features2d opencv_flann opencv_3d opencv_stereo ${debug_modules} |
||||
WRAP java objc python js |
||||
) |
@ -0,0 +1,12 @@ |
||||
@inproceedings{strobl2011iccv, |
||||
title={More accurate pinhole camera calibration with imperfect planar target}, |
||||
author={Strobl, Klaus H. and Hirzinger, Gerd}, |
||||
booktitle={2011 IEEE International Conference on Computer Vision (ICCV)}, |
||||
pages={1068-1075}, |
||||
month={Nov}, |
||||
year={2011}, |
||||
address={Barcelona, Spain}, |
||||
publisher={IEEE}, |
||||
url={https://elib.dlr.de/71888/1/strobl_2011iccv.pdf}, |
||||
doi={10.1109/ICCVW.2011.6130369} |
||||
} |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue