Błąd w obliczaniu transformacji perspektywy dla opencv w Matlab
Próbuję przekodowaćdopasowanie funkcji i homografia za pomocąmexopencv .Mexopencv przenosi zestaw narzędzi wizyjnych OpenCV do Matlab.
Mój kod w Matlab przy użyciu zestawu narzędzi 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
Błąd:
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);
Problem zaczyna się od sprawdzeniaperspectiveTranform(boxCorners, H)
, aż do znalezieniahomography
To było fajne . Zauważ również, że podczas obliczania współrzędnych pasujących do próbki i sceny, zindeksowałem2:end
, box = [boxPoints([matches(2:end).queryIdx]).pt]
, od dostępu doqueryIdx
pierwszego elementu da zerową pozycję, do której nie można uzyskać dostępu. Myślę jednak, że to nie byłby problem. W każdym razie czekam na odpowiedź na moje rozwiązanie. Dzięki.
PS: To jest edytowana wersja mojego oryginalnego posta tutaj. Rozwiązanie, które otrzymałem poniżej, nie było wystarczające, a błąd wciąż się powtarzał.
Druga aktualizacja:Według @Amro zaktualizowałem swój kod poniżej. Inliers daje dobrą odpowiedź, jednak współrzędne obliczania transformacji perspektywy zostały w jakiś sposób skręcone.
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
Jednak wyjście jest w porządkuperspectiveTranform
nie podaje odpowiednich współrzędnych do problemu. Moje wyniki do tej pory:
Mam cały kod działający z homografią. Jednak przypadek narożny bardzo mnie dręczy. Jeśli zrobięimgObj = imread('D:/pic/box.png')
iimgScene = imread('D:/pic/box_in_scene.png')
, Jednak, kiedy robię, dostaję prostokąt homografii dobry i dobryimgScene = imread('D:/pic/box.png')
, tj. obiekt i scena sąpodobnie , Dostaję ten błąd -
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');
Teraz natknąłem się na ten błąd w przeszłości, dzieje się tak, gdy liczbaptsObj
lubptsScene
jest niska, np. gdy scena jest niczym innym jak białym / czarnym ekranem, punkty kluczowe tej sceny są zerowe. W tym szczególnym problemie jest dużoptsObj
iptsScene
. Gdzie może leżeć problem. Przetestowałem ten kod za pomocąSURF
ten sam błąd to zmiana powierzchni.