1

関数はテンプレート画像を 0 から 180 度 (または最大 360 度) 回転させて、縮尺が異なっていてもソース画像内の関連するすべての一致 (すべての角度) を検索します。

関数は OpenCV C インターフェイスで記述されていました。それを openCV C++ インターフェイスに移植しようとすると、多くのエラーが発生します。OpenCV C++インターフェイスに移植するのを手伝ってください。

  void TemplateMatch()
  {

    int i, j, x, y, key;
    double minVal;
    char windowNameSource[] = "Original Image";
    char windowNameDestination[] = "Result Image";
    char windowNameCoefficientOfCorrelation[] = "Coefficient of Correlation Image";
     CvPoint minLoc;
     CvPoint tempLoc;

     IplImage *sourceImage = cvLoadImage("template_source.jpg", CV_LOAD_IMAGE_ANYDEPTH         | CV_LOAD_IMAGE_ANYCOLOR);
     IplImage *templateImage = cvLoadImage("template.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);


   IplImage *graySourceImage = cvCreateImage(cvGetSize(sourceImage), IPL_DEPTH_8U, 1); 
   IplImage *grayTemplateImage =cvCreateImage(cvGetSize(templateImage),IPL_DEPTH_8U,1);
   IplImage *binarySourceImage = cvCreateImage(cvGetSize(sourceImage), IPL_DEPTH_8U, 1); 
  IplImage *binaryTemplateImage = cvCreateImage(cvGetSize(templateImage), IPL_DEPTH_8U, 1); 
  IplImage *destinationImage = cvCreateImage(cvGetSize(sourceImage), IPL_DEPTH_8U, 3); 

  cvCopy(sourceImage, destinationImage);

  cvCvtColor(sourceImage, graySourceImage, CV_RGB2GRAY);
  cvCvtColor(templateImage, grayTemplateImage, CV_RGB2GRAY);

  cvThreshold(graySourceImage, binarySourceImage, 200, 255, CV_THRESH_OTSU );
  cvThreshold(grayTemplateImage, binaryTemplateImage, 200, 255, CV_THRESH_OTSU);

  int templateHeight = templateImage->height;
  int templateWidth = templateImage->width;

 float templateScale = 0.5f;

  for(i = 2; i <= 3; i++) 
   {

    int tempTemplateHeight = (int)(templateWidth * (i * templateScale));
    int tempTemplateWidth = (int)(templateHeight * (i * templateScale));

    IplImage *tempBinaryTemplateImage = cvCreateImage(cvSize(tempTemplateWidth,                  tempTemplateHeight), IPL_DEPTH_8U, 1);

    // W - w + 1, H - h + 1

    IplImage *result = cvCreateImage(cvSize(sourceImage->width - tempTemplateWidth + 1,      sourceImage->height - tempTemplateHeight + 1), IPL_DEPTH_32F, 1);

    cvResize(binaryTemplateImage, tempBinaryTemplateImage, CV_INTER_LINEAR);
    float degree = 20.0f;
  for(j = 0; j <= 9; j++) 
    {

     IplImage *rotateBinaryTemplateImage = cvCreateImage(cvSize(tempBinaryTemplateImage-  >width, tempBinaryTemplateImage->height), IPL_DEPTH_8U, 1);

       //cvShowImage(windowNameSource, tempBinaryTemplateImage);  
      //cvWaitKey(0);             

        for(y = 0; y < tempTemplateHeight; y++)
          {

         for(x = 0; x < tempTemplateWidth; x++)
          {
            rotateBinaryTemplateImage->imageData[y * tempTemplateWidth + x] = 255;

          }         
          }


       for(y = 0; y < tempTemplateHeight; y++)
         {

        for(x = 0; x < tempTemplateWidth; x++)
          {

       float radian = (float)j * degree * CV_PI / 180.0f;
       int scale = y * tempTemplateWidth + x;

       int rotateY = - sin(radian) * ((float)x - (float)tempTemplateWidth / 2.0f) + cos(radian) * ((float)y - (float)tempTemplateHeight / 2.0f) + tempTemplateHeight / 2;

      int rotateX = cos(radian) * ((float)x - (float)tempTemplateWidth / 2.0f) + sin(radian) * ((float)y - (float)tempTemplateHeight / 2.0f) + tempTemplateWidth / 2;


      if(rotateY < tempTemplateHeight && rotateX < tempTemplateWidth && rotateY >= 0 && rotateX  >= 0)

      rotateBinaryTemplateImage->imageData[scale] = tempBinaryTemplateImage->imageData[rotateY * tempTemplateWidth + rotateX];

    }
   }

    //cvShowImage(windowNameSource, rotateBinaryTemplateImage);
    //cvWaitKey(0);

   cvMatchTemplate(binarySourceImage, rotateBinaryTemplateImage, result, CV_TM_SQDIFF_NORMED); 

   //cvMatchTemplate(binarySourceImage, rotateBinaryTemplateImage, result, CV_TM_SQDIFF);  

   cvMinMaxLoc(result, &minVal, NULL, &minLoc, NULL, NULL);
   printf(": %f%%\n", (int)(i * 0.5 * 100), j * 20, (1 - minVal) * 100);    

   if(minVal < 0.065) // 1 - 0.065 = 0.935 : 93.5% 
    {
      tempLoc.x = minLoc.x + tempTemplateWidth;
      tempLoc.y = minLoc.y + tempTemplateHeight;
     cvRectangle(destinationImage, minLoc, tempLoc, CV_RGB(0, 255, 0), 1, 8, 0);

    }
    }

    //cvShowImage(windowNameSource, result);
    //cvWaitKey(0);

    cvReleaseImage(&tempBinaryTemplateImage);
    cvReleaseImage(&result);

   }

   // cvShowImage(windowNameSource, sourceImage);
   // cvShowImage(windowNameCoefficientOfCorrelation, result); 

    cvShowImage(windowNameDestination, destinationImage);
    key = cvWaitKey(0);

    cvReleaseImage(&sourceImage);
    cvReleaseImage(&templateImage);
    cvReleaseImage(&graySourceImage);
    cvReleaseImage(&grayTemplateImage);
    cvReleaseImage(&binarySourceImage);
    cvReleaseImage(&binaryTemplateImage);
    cvReleaseImage(&destinationImage);

    cvDestroyWindow(windowNameSource);
    cvDestroyWindow(windowNameDestination);
    cvDestroyWindow(windowNameCoefficientOfCorrelation);

     }

結果 :

テンプレート画像:

ここに画像の説明を入力

結果画像:

上記の関数は、この画像の完全一致 (角度とスケールの不変) の周りに長方形を配置します .....

ここに画像の説明を入力

現在、コードを C++ インターフェイスに移植しようとしています。詳細が必要な場合は、お知らせください。

4

1 に答える 1