I am using VS2012 C++/CLI with OpenCV 3.1 and Win10.
I am trying to get cameracalibration working and appear to be having an issue with converting the vector of Point2f returned by findChessboardCorners to a UMat either just generally or for use with drawChessboardCorners.
Calling drawChessboardCorners or even just trying to convert the vector to a UMat causes an exception. Checking the pointBuf vector after findChessboardCorners indicates that the vector is not empty. I am not sure why I get this runtime exception and any help or even indication of how better to debug it is appreciated.
MY code is as follows and crashes on either the commented out drawChessboardCorners call or the effort to convert the pointBuf vector to a UMat called tpoints.
void Channel::Calibration(videoInput* CameraVI,bool Enabled,int CameraNumber, unsigned char * LdataBuffer, cvImages* Images,int ChannelNumber,bool MirrorH, bool MirrorV, bool MainWinCond,ImageSource^ ImageEvents)
{
int totalframes = 0;
int numCornersHor = CALIBRATE_CORNERS_HORIZONTAL;
int numCornersVer = CALIBRATE_CORNERS_VERTICAL;
Size board_sz = Size(numCornersHor,numCornersVer);
std::vector<std::vector<Point2f> > imagePoints;
int successes = 0;
UMat tImage;
UMat grayImage;
System::String^ tfname;
UMat tpoints;
bool found = false;
TermCriteria criteria = TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 );
long mDefaultmin,mDefaultmax,mDefaultStep,mDefaultFlags,mDefaultValue;
long mDefaultfocus,mDefaultzoom;
Size imageSize;
std::vector<Point2f> pointBuf;
int tpointBufsize;
if(Enabled)
{
CameraVI->setVideoSettingCamera(CameraNumber,CameraControl_Focus,mDefaultfocus,CameraControl_Flags_Manual);
CameraVI->getVideoSettingCamera(CameraNumber,CameraControl_Zoom,mDefaultmin,mDefaultmax,mDefaultStep,mDefaultzoom,mDefaultFlags,mDefaultValue);
CameraVI->setVideoSettingCamera(CameraNumber,CameraControl_Zoom,mDefaultzoom,CameraControl_Flags_Manual);
while(successes<CALIBRATE_NUMBER_OF_BOARDS_TO_MATCH && totalframes<CALIBRATE_TOTAL_FRAMES)
{
pointBuf.clear();
// check for new image
if(CameraVI->isFrameNew(CameraNumber))
{
totalframes++;
// load the image from the buffer
CameraVI->getPixels(CameraNumber, LdataBuffer, false, true);
// convert it to a mat
cv::Mat ttImage(Images->Height, Images->Width, CV_8UC3, LdataBuffer, UMat::AUTO_STEP);
cv::UMat tImage = ttImage.getUMat(ACCESS_RW);
found = findChessboardCorners(tImage, board_sz, pointBuf, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK| CV_CALIB_CB_NORMALIZE_IMAGE);
if(found)
{
cvtColor(tImage,grayImage,CV_BGR2GRAY);
cornerSubPix( grayImage, pointBuf, Size(11,11), Size(-1,-1), criteria);
imagePoints.push_back(pointBuf);
successes++;
putText(tImage,msclr::interop::marshal_as<std::string>("Calibrate Successes: " + successes.ToString() + " TotalFrames: " + totalframes.ToString()),Point(40,40),FONT_HERSHEY_SIMPLEX,1.5,OPENCV_WHITE,3);
tpointBufsize = pointBuf.size();
// drawChessboardCorners( tImage, board_sz, UMat(pointBuf), found );
Sleep(2000);
}
else
putText(tImage,msclr::interop::marshal_as<std::string>("Calibrate Successes: " + successes.ToString() + " TotalFrames: " + totalframes.ToString()),Point(40,40),FONT_HERSHEY_SIMPLEX,1.5,OPENCV_WHITE,3);
tpoints = UMat(pointBuf,false);
ImageEvents->FireCVImage(ChannelNumber,MainWinCond,tImage);
}
Sleep(200);
}
CameraVI->setVideoSettingCamera(CameraNumber,CameraControl_Zoom,mDefaultzoom,CameraControl_Flags_Auto);
imageSize = tImage.size();
std::vector<UMat> rvecs, tvecs;
std::vector<float> reprojErrs;
Calibrated = runCalibration(tImage, CALIBRATE_SQUARE_SIZE , grayImage.size(), imagePoints, rvecs, tvecs, reprojErrs);
ImageEvents->FireCVCalibrationDetails(ChannelNumber,Calibrated,*intrinsic,*distCoeffs,RMS,totalAVGErr);
initUndistortRectifyMap(*intrinsic, *distCoeffs,cv::UMat(),*intrinsic,imageSize,CV_16SC2,*map1,*map2);
saveCameraCalibration(gcnew System::String(CameraPath) + Images->Width.ToString() + "x" + Images->Height.ToString() + "y.xml");
}
else
ImageEvents->FireCVStatus(ChannelNumber,"Calibrate Camera Not Enabled!");
}