基本的にトランプを検出し、HSV 設定に基づいて動的な背景からそれらを分離し、輪郭を使用してカードの 4 点を検出し、カードの正確な x および y 位置を見つけるコードがあります。そこから、ROI が設定され、カードの額面を検出するためのさらなる処理を実行できます。
ただし、コードが壊れているようで、根本的な原因を見つけることができないようです。画像とメモリ ストレージをクリアし、すべての Iplimage のフォーマットと解像度が同じであることを確認しました。
IplImage* GetThresholdedImage(IplImage* imgHSV){
IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1);
cvInRangeS(imgHSV, cvScalar(95,67,170), cvScalar(110,119,254), imgThresh); //Morning
return imgThresh;
}
IplImage* RedCheck(IplImage* imgBGR){
IplImage* img=cvCreateImage(cvGetSize(imgBGR),IPL_DEPTH_8U, 1);
cvInRangeS(imgBGR, cvScalar(0,0,100), cvScalar(100,100,254), img); //BGR
return img;
}
int main()
{
CvCapture* capture =0;
capture = cvCaptureFromCAM(0);
if(!capture)
{
printf("Capture failure\n");
return -1;
}
IplImage* frame = cvCreateImage(cvSize(48,64),IPL_DEPTH_8U,3);
while(true)
{
frame = cvQueryFrame(capture);
if(!frame) break;
frame=cvCloneImage(frame);
cvSmooth(frame, frame, CV_GAUSSIAN,3,3); //smooth the original image using Gaussian kernel
IplImage* imgHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
cvCvtColor(frame, imgHSV, CV_BGR2HSV); //Change the color format from BGR to HSV
IplImage* imgThresh = GetThresholdedImage(imgHSV);
cvSmooth(imgThresh, imgThresh, CV_GAUSSIAN,3,3); //smooth the binary image using Gaussian kernel
CvSeq* contours;
CvSeq* result;
CvMemStorage *storage = cvCreateMemStorage(0);
cvFindContours(imgThresh, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
while(contours)
{
result = cvApproxPoly(contours, sizeof(CvContour),storage,CV_POLY_APPROX_DP,cvContourPerimeter(contours)*0.02,0);
if(result->total == 4)
{
CvPoint *pt[4];
for(int i=0;i<4;i++)
{
pt[i] = (CvPoint*)cvGetSeqElem(result,i);
}
if (cvArcLength(result,CV_WHOLE_SEQ,1) >= 400)
{
cvLine(imgThresh,*pt[0],*pt[1],cvScalar(255,0,0),4);
cvLine(imgThresh,*pt[1],*pt[2],cvScalar(255,0,0),4);
cvLine(imgThresh,*pt[2],*pt[3],cvScalar(255,0,0),4);
cvLine(imgThresh,*pt[3],*pt[0],cvScalar(255,0,0),4);
int ROIwidth = abs((*pt[0]).x - (*pt[1]).x);
int ROIheight = abs((*pt[1]).y - (*pt[2]).y);
cvSetImageROI(frame,cvRect((*pt[1]).x,(*pt[1]).y,ROIwidth,ROIheight));
IplImage* temp = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3);
cvCopy(frame,temp,0);
cvResetImageROI(frame);
cvNamedWindow( "ROI", CV_WINDOW_AUTOSIZE );
cvShowImage( "ROI", temp);
printf("Width = %d\n",ROIwidth); //255-275
printf("Height = %d\n",ROIheight); //140-160
//Card Value Detection Starts Here
IplImage* colorcheck = RedCheck(temp);
int redpixelcheck = cvCountNonZero(colorcheck);
if (redpixelcheck <= 15)
{
printf("Card is Black\n");
}
else if (redpixelcheck >= 16)
{
printf("Card is Red\n");
}
//Card Value Detection Ends Here
cvReleaseImage(&temp);
cvReleaseImage(&frame);
cvReleaseImage(&colorcheck);
delete &ROIwidth;
delete &ROIheight;
delete &redpixelcheck;
}
//delete [] pt[4];
}
delete &result;
contours = contours->h_next;
//cvPutText (frame_t,text,cvPoint(200,400), &font, cvScalar(255,255,0));
}
cvNamedWindow( "Contour", CV_WINDOW_AUTOSIZE );
cvShowImage( "Contour", imgThresh);
cvNamedWindow("Video",CV_WINDOW_AUTOSIZE);
cvShowImage("Video", frame);
//Clean up used images
cvReleaseImage(&imgHSV);
cvReleaseImage(&imgThresh);
cvReleaseImage(&frame);
cvClearMemStorage(storage);
cvReleaseMemStorage(&storage);
//Wait 50mS
int c = cvWaitKey(10);
//If 'ESC' is pressed, break the loop
if((char)c==27 ) break;
}
cvDestroyAllWindows() ;
cvReleaseCapture(&capture);
return 0;
}
逆アセンブリは常に同じアドレス 770915DE add esp,4 を指します