2015-07-15 18 views
5

Też poprosiłem o to na forum OpenCV, próbuję swojego szczęścia gdzie indziej. Używam OpenCV 3.0 w Visual Studio Professional 2013.Problem OpenCV z findChessboardCorners

Próbuję więc skalibrować kamerę za pomocą kodu samouczka w samouczku calib3d i this. Wciąż pojawia się ten sam błąd w kółko (std :: length_error w lokalizacji pamięci) i wyśledziłem go tam, gdzie próbuję i dodaję wektor narożny podany z findChessboardCorners do wektora image_points w ostatniej linii mojego kodu.

image_points.push_back(corners); 

W oknie debugowania, wielkość narożników znajduje się na liście: rogi {size = 2305843009213050645}, co jest oczywiście zbyt duża (istnieją tylko 35 narożniki w obrazie kalibracji używam).

Poniższy kod tutoriala znajduje się poniżej, choć ponownie wyizolowałem problem, aby findChessboardCorners dał pozornie bezsensowny wektor narożny. Dziwne jest to, że nie ma problemu z rysowaniem narożników na obrazie kalibracyjnym, którego używam - wygląda na to, że narożniki zostały idealnie skalibrowane. Więc jaki jest problem? Naprawdę nie wiem, dlaczego findChessboardCorners dałoby mi tak duży narożny wektor, że nie mogę go nawet dodać do listy wektorów.

using namespace cv; 
using namespace std; 

int main(int argc, char** argv){ 

int numBoards = 1; 
int numCornersHor=7; 
int numCornersVer=5; 

int numSquares = numCornersHor * numCornersVer; 
Size board_sz = Size(numCornersHor, numCornersVer); 

vector<vector<Point3f>> object_points; 
vector<vector<Point2f>> image_points; 

vector<Point2f> corners; 

int successes = 0; 

Mat large_image; 
Mat image; 
Mat gray_image; 
large_image = imread(argv[1], IMREAD_COLOR); 
resize(large_image, image, Size(), .5, .5); 

vector<Point3f> obj; 
for (int j = 0; j<numSquares; j++) 
    obj.push_back(Point3f((j/numCornersHor)*29, (j%numCornersHor)*29, 0.0f)); 

if (image.empty()) 
     return(0); 
else if (image.channels()>1) 
    cvtColor(image, gray_image, CV_BGR2GRAY); 
else gray_image = image; 

bool found = findChessboardCorners(image, board_sz, corners, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE); 


if (found) 
{ 
    cornerSubPix(gray_image, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1)); 

    drawChessboardCorners(gray_image, board_sz, corners, found); 

} 

imshow("win1", image);  
imshow("win2", gray_image); 

int key = waitKey(1); 
if (key == 27) 
    return 0; 

image_points.push_back(corners); 
} 

Odpowiedz

1

Wyliczyłem to. Problem był błędem w findChessboardCorners - kąty były nieprawidłowo zmieniane w samej funkcji, powodując jej wysadzenie w powietrze. Znaleźliśmy problem i dostałem poprawkę od here, chociaż musiałem zamienić rogi z powrotem na wektor po uruchomieniu poprawionej funkcji.

Zaktualizowany kod:

Mat pointBuf; 

found = actually_findChessboardCorners(image, board_sz, pointBuf, 
      CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE); 

corners.assign((Point2f*)pointBuf.datastart, (Point2f*)pointBuf.dataend); 

użyciem tej funkcji:

bool actually_findChessboardCorners(Mat& frame, Size& size, Mat& corners, int flags) { 
int count = size.area() * 2; 
corners.create(count, 1, CV_32FC2); 
CvMat _image = frame; 
bool ok = cvFindChessboardCorners(&_image, size, 
    reinterpret_cast<CvPoint2D32f*>(corners.data), 
    &count, flags) > 0; 
return ok; 

}

+0

Kiedyś Ci rozwiązania i wciąż mają problem z twierdzenie nie powiodło 'cornerSubPix'. Czy masz ten problem? – Misaki