Error al calcular la transformación de perspectiva para opencv en Matlab
Estoy tratando de recodificarcomparación de características y homografía utilizandomexopencv .Mexopencv abre el cuadro de herramientas de visión de OpenCV a Matlab.
Mi código en Matlab usando la caja de herramientas de OpenCV:
function hello
close all;clear all;
disp('Feature matching demo, press key when done');
boxImage = imread('D:/pic/500_1.jpg');
boxImage = rgb2gray(boxImage);
[boxPoints,boxFeatures] = cv.ORB(boxImage);
sceneImage = imread('D:/pic/100_1.jpg');
sceneImage = rgb2gray(sceneImage);
[scenePoints,sceneFeatures] = cv.ORB(sceneImage);
if (isempty(scenePoints)|| isempty(boxPoints))
return;
end;
matcher = cv.DescriptorMatcher('BruteForce');
matches = matcher.match(boxFeatures,sceneFeatures);
%Box contains pixels coordinates where there are matches
box = [boxPoints([matches(2:end).queryIdx]).pt];
%Scene contains pixels coordinates where there are matches
scene = [scenePoints([matches(2:end).trainIdx]).pt];
%Please refer to http://stackoverflow.com/questions/4682927/matlab-using-mat2cell
%Box arrays contains coordinates the form [ (x1,y1), (x2,y2) ...]
%after applying mat2cell function
[nRows, nCols] = size(box);
nSubCols = 2;
box = mat2cell(box,nRows,nSubCols.*ones(1,nCols/nSubCols));
%Scene arrays contains coordinates the form [ (x1,y1), (x2,y2) ...]
%after applying mat2cell function
[nRows, nCols] = size(scene);
nSubCols = 2;
scene = mat2cell(scene,nRows,nSubCols.*ones(1,nCols/nSubCols));
%Finding homography between box and scene
H = cv.findHomography(box,scene);
boxCorners = [1, 1;... % top-left
size(boxImage, 2), 1;... % top-right
size(boxImage, 2), size(boxImage, 1);... % bottom-right
1, size(boxImage, 1)];
%Fine until this point , problem starts with perspectiveTransform
sceneCorners= cv.perspectiveTransform(boxCorners,H);
end
El error:
Error using cv.perspectiveTransform
Unexpected Standard exception from MEX file.
What()
is:C:\slave\builds\WinInstallerMegaPack\src\opencv\modules\core\src\matmul.cpp:1926:
error: (-215) scn + 1 == m.cols && (depth == CV_32F || depth == CV_64F)
..
Error in hello (line 58)
sceneCorners= cv.perspectiveTransform(boxCorners,H);
El problema comienza desde la comprobación de laperspectiveTranform(boxCorners, H)
, hasta encontrarhomography
estuvo bien . También tenga en cuenta que al calcular las coordenadas coincidentes de la muestra y la escena, indice desde2:end
, box = [boxPoints([matches(2:end).queryIdx]).pt]
, desde que accedemos a laqueryIdx
del primer elemento produciría la posición cero que no se pudo acceder. Sin embargo, creo que esto no sería un problema. De todos modos, estoy esperando una respuesta a mi solución. Gracias.
PD: Esta es una versión editada de mi publicación original aquí. La solución que recibí a continuación, no fue lo suficientemente adecuada y el error se repitió.
2da actualización:Según @Amro, he actualizado mi código, a continuación. Los inliers dan una buena respuesta, sin embargo, las coordenadas para calcular la transformación de perspectiva de alguna manera se torcieron.
function hello
close all; clear all; clc;
disp('Feature matching with ORB');
%Feature detector and extractor for object
imgObj = imread('D:/pic/box.png');
%boxImage = rgb2gray(boxImage);
[keyObj,featObj] = cv.ORB(imgObj);
%Feature detector and extractor for scene
imgScene = imread('D:/pic/box_in_scene.png');
%sceneImage = rgb2gray(sceneImage);
[keyScene,featScene] = cv.ORB(imgScene);
if (isempty(keyScene)|| isempty(keyObj))
return;
end;
matcher = cv.DescriptorMatcher('BruteForce-HammingLUT');
m = matcher.match(featObj,featScene);
%im_matches = cv.drawMatches(boxImage, boxPoints, sceneImage, scenePoints,m);
% extract keypoints from the filtered matches
% (C zero-based vs. MATLAB one-based indexing)
ptsObj = cat(1, keyObj([m.queryIdx]+1).pt);
ptsObj = num2cell(ptsObj, 2);
ptsScene = cat(1, keyScene([m.trainIdx]+1).pt);
ptsScene = num2cell(ptsScene, 2);
% compute homography
[H,inliers] = cv.findHomography(ptsObj, ptsScene, 'Method','Ransac');
% remove outliers reported by RANSAC
inliers = logical(inliers);
m = m(inliers);
% show the final matches
imgMatches = cv.drawMatches(imgObj, keyObj, imgScene, keyScene, m, ...
'NotDrawSinglePoints',true);
imshow(imgMatches);
% apply the homography to the corner points of the box
[h,w] = size(imgObj);
corners = permute([0 0; w 0; w h; 0 h], [3 1 2]);
p = cv.perspectiveTransform(corners, H)
p = permute(p, [2 3 1])
p = bsxfun(@plus, p, [size(imgObj,2) 0]);
% draw lines between the transformed corners (the mapped object)
opts = {'Color',[0 255 0], 'Thickness',4};
imgMatches = cv.line(imgMatches, p(1,:), p(2,:), opts{:});
imgMatches = cv.line(imgMatches, p(2,:), p(3,:), opts{:});
imgMatches = cv.line(imgMatches, p(3,:), p(4,:), opts{:});
imgMatches = cv.line(imgMatches, p(4,:), p(1,:), opts{:});
imshow(imgMatches)
title('Matches & Object detection')
end
La salida está bien, sin embargo, laperspectiveTranform
No está dando las coordenadas correctas a propósito del problema. Mi salida hasta ahora:
Tengo todo el código funcionando y bien con la homografía. Sin embargo, un caso de esquina me está molestando muy duro. Si lo hagoimgObj = imread('D:/pic/box.png')
yimgScene = imread('D:/pic/box_in_scene.png')
, Me sale bien el rectángulo de homografía, sin embargo, cuando lo hagoimgScene = imread('D:/pic/box.png')
, es decir, el objeto y la escena son losmismo , Me sale este error -
Error using cv.findHomography
Unexpected Standard exception from MEX file.
What()
is:C:\slave\builds\WinInstallerMegaPack\src\opencv\modules\calib3d\src\fundam.cpp:1074:
error: (-215) npoints >= 0 && points2.checkVector(2) == npoints && points1.type() ==
points2.type()
..
Error in hello (line 37)
[H,inliers] = cv.findHomography(ptsObj, ptsScene, 'Method','Ransac');
Ahora, me he encontrado con este error en el pasado, esto sucede cuando el número deptsObj
optsScene
es bajo, por ejemplo, cuando la escena no es más que una pantalla en blanco / negro, los puntos clave de esa escena son cero. En este problema particular hay una gran cantidad deptsObj
yptsScene
. ¿Dónde está el problema? He probado este código utilizandoSURF
Un mismo error está resurgiendo.