OpenCVでテンプレートマッチングを行うソースコードを作ったのでシェアします。
解析結果を合成した画像を/tmp/result.jpgに生成するようにしてあります。 mjpeg_streamerのinput_file.soなどと組み合わせることで、結果を簡単に確認することができます。
Makefile
CROSS_COMPILE ?= arm-linux-gnueabihf-
CC = $(CROSS_COMPILE)gcc
CFLAGS = -Wall -O2
EXEC = template_match
OBJS = template_match.o
LDLIBS := -lopencv_core -lopencv_highgui -lopencv_imgproc -lm
all: $(EXEC)
$(EXEC): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
romfs:
$(ROMFSINST) /usr/bin/$(EXEC)
clean:
rm -f $(OBJS) $(EXEC)
template_match.c
#include
#include
#include
#include
#include
void myOutputInit(char *wname)
{
#ifndef arm
cvNamedWindow(wname, CV_WINDOW_AUTOSIZE);
#endif
}
void myOutput(char *wname, IplImage *output)
{
#ifdef arm
cvSaveImage("/tmp/result.jpg", output, NULL);
#else
cvShowImage(wname, output);
cvWaitKey(10);
#endif
}
void myOutputRelease(char *wname)
{
#ifndef arm
cvDestroyWindow(wname);
#endif
}
IplImage *match_func(IplImage *testimg, IplImage *templateimg,
IplImage *outputimg)
{
IplImage *resultimg;
double maxval;
CvPoint maxloc;
clock_t start, end;
resultimg = cvCreateImage(cvSize(testimg->width - templateimg->width + 1, testimg->height - templateimg->height + 1), 32, 1);
start = clock();
cvMatchTemplate(testimg, templateimg, resultimg, CV_TM_CCOEFF_NORMED);
end = clock();
printf("processing time: %.2f [s]\n",
(double)(end - start) / CLOCKS_PER_SEC);
cvMinMaxLoc(resultimg, NULL, &maxval, NULL, &maxloc, NULL);
printf("(%3d,%3d), score=%f\n", maxloc.x, maxloc.y, maxval);
cvCopy(testimg, outputimg, NULL);
if (maxval > 0.25)
cvRectangle(outputimg, maxloc,
cvPoint(maxloc.x + templateimg->width,
maxloc.y + templateimg->height),
CV_RGB(255, 0, 0), 3, 8, 0);
cvReleaseImage(&resultimg);
return outputimg;
}
int main(int argc, char *argv[])
{
IplImage *testimg, *templateimg, *outputimg;
CvCapture *capture;
int video_dev = 0;
char templateimgfile[] = "template.jpg";
int i;
if (argc > 1)
video_dev = atoi(argv[1]);
capture = cvCreateCameraCapture(video_dev);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 240);
if ((testimg = cvQueryFrame (capture)) == NULL) {
fprintf(stderr, "camera device not found.\n");
return -EIO;
}
templateimg = cvLoadImage(templateimgfile,
(CV_LOAD_IMAGE_ANYCOLOR |
CV_LOAD_IMAGE_ANYDEPTH));
outputimg = cvCreateImage(cvGetSize(testimg), IPL_DEPTH_8U, 3);
myOutputInit("Output1");
for (i=0; ; i++) {
testimg = cvQueryFrame(capture);
if (testimg == NULL) {
fprintf(stderr, "failed to query frame.\n");
return -EIO;
}
outputimg = match_func(testimg, templateimg, outputimg);
myOutput("Output1", outputimg);
}
myOutputRelease("Output1");
cvReleaseImage(&outputimg);
cvReleaseImage(&templateimg);
cvReleaseImage(&testimg);
return 0;
}