#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#define PI 3.1415926
#define Wa 0.5
#define Wb 0.4
#define Wc 0.1
#define Nh 18
#define Ns 3
#define Nv 3
CvPoint pt_beg = {-1,-1};
CvPoint pt_end = {-1,-1};
CvPoint pt1 = {-1,-1};
CvPoint pt2 = {-1,-1};
IplImage *src = 0;
IplImage *img = 0;
void on_mouse(int event, int x, int y, int flags, void *zhang)
{
if(event == CV_EVENT_LBUTTONDOWN)
{
pt_beg = cvPoint(x, y);
}
else if(event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
{
cvCopy(src, img);
CvPoint pt = cvPoint(x, y);
pt1.x = pt.x;
pt1.y = pt_beg.y;
pt2.x = pt_beg.x;
pt2.y = pt.y;
cvLine(img, pt_beg, pt1, CV_RGB(255, 0, 0), 1, 8, 0);
cvLine(img, pt_beg, pt2, CV_RGB(255, 0, 0), 1, 8, 0);
cvLine(img, pt1, pt, CV_RGB(255, 0, 0), 1, 8, 0);
cvLine(img, pt2, pt, CV_RGB(255, 0, 0), 1, 8, 0);
pt_end = pt;
cvShowImage("SRC", img);
}
}
void QuickSort(double pData[][5], int left, int right)
{
int i = left;
int j = right;
double middle = pData[(left + right) / 2][0];
double iTemp[5] = {0};
do{
while ((pData[i][0] > middle) && (i < right))
{
i++;
}
while ((pData[j][0] < middle) && (j > left))
{
j--;
}
if (i <= j)
{
memcpy(iTemp, pData[i], sizeof(iTemp));
memcpy(pData[i], pData[j], sizeof(pData[i]));
memcpy(pData[j], iTemp, sizeof(pData[j]));
i++;
j--;
}
}while(i <= j);
if (left < j)
{
QuickSort(pData, left, j);
}
if (right > i)
{
QuickSort(pData, i, right);
}
}
void cal_HSV(IplImage *image, int num, double hist[][5])
{
int Row = image->height;
int Col = image->width;
int step = image->widthStep / sizeof(float);
int channel = image->nChannels;
float *data = (float*)image->imageData;
double H, S, V;
int h, s, v, n;
for(int i = 0; i < Row; i++)
{
for(int j = 0; j < Col; j++)
{
int k = i * step + j * channel;
H = data[k + 0];
S = data[k + 1];
V = data[k + 2];
h = cvFloor(H / 20.0);
s = cvFloor(S / 0.3);
v = cvFloor(V / 0.3);
h = h == 0 ? 1 : h;
s = s == 0 ? 1 : s;
v = v == 0 ? 1 : v;
n = h * s * v;
hist[n][1] = hist[n][1] + H;
hist[n][2] = hist[n][2] + S;
hist[n][3] = hist[n][3] + V;
hist[n][4]++;
if(num == 0 || num == 3 || num == 12 || num == 15)
{
hist[n][0] = hist[n][0] + Wc;
}
else if(num == 1 || num == 2 || num == 4 || num == 7 || num == 8 || num == 11 || num == 13 || num == 14)
{
hist[n][0] = hist[n][0] + Wb;
}
else if(num == 5 || num == 6 || num == 9 || num == 10)
{
hist[n][0] = hist[n][0] + Wa;
}
}
}
}
void cal_DCD(IplImage *image, double bin[])
{
int Row = image->height / 4 * 4;
int Col = image->width / 4 * 4;
int row = Row / 4;
int col = Col / 4;
double q[Nh * Ns * Nv + 1][5] = {0};
IplImage *RGB_Image = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 3);
IplImage *HSV_Image = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 3);
cvConvertScale(image, RGB_Image, 1 / 255.0, 0);
cvCvtColor(RGB_Image, HSV_Image, CV_BGR2HSV);
int num = 0;
double sum = 0;
for(int i = 0; i < Row; i += row)
{
for(int j = 0; j < Col; j += col)
{
IplImage *subImage = cvCreateImage(cvSize(col, row), HSV_Image->depth, HSV_Image->nChannels);
CvRect rect = cvRect(j, i, col, row);
cvSetImageROI(HSV_Image, rect);
cvCopyImage(HSV_Image, subImage);
cal_HSV(subImage, num, q);
cvResetImageROI(HSV_Image);
cvReleaseImage(&subImage);
num++;
}
}
for (int i = 0; i < Nh * Ns * Nv + 1; i++)
{
sum = sum + q[i][0];
}
sum = sum == 0 ? 1 : sum;
QuickSort(q, 0, Nh * Ns * Nv);
for(int i = 0; i < 8; i++)
{
bin[i * 4 + 0] = q[i][0] / sum;
q[i][4] = q[i][4] == 0 ? 1 : q[i][4];
bin[i * 4 + 1] = q[i][1] / q[i][4];
bin[i * 4 + 2] = q[i][2] / q[i][4];
bin[i * 4 + 3] = q[i][3] / q[i][4];
}
cvReleaseImage(&RGB_Image);
cvReleaseImage(&HSV_Image);
}
double computeD(double src[], double dst[])
{
double rate = 0;
double rate1 = 0;
double rate2 = 0;
double rate3 = 0;
double d1;
double d2;
double d3;
int Mi0, Mi1, Mi2, Mi3;
int Mj0, Mj1, Mj2, Mj3;
double h1, s1, v1, H1, S1, V1;
double h2, s2, v2, H2, S2, V2;
double h3, s3, v3, H3, S3, V3;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
Mi0 = i * 4 + 0;
Mi1 = i * 4 + 1;
Mi2 = i * 4 + 2;
Mi3 = i * 4 + 3;
Mj0 = j * 4 + 0;
Mj1 = j * 4 + 1;
Mj2 = j * 4 + 2;
Mj3 = j * 4 + 3;
h1 = src[Mi2] * sin(src[Mi1] / 180 * PI) - src[Mj2] * sin(src[Mj1] / 180 * PI);
s1 = src[Mi2] * cos(src[Mi1] / 180 * PI) - src[Mj2] * cos(src[Mj1] / 180 * PI);
v1 = src[Mi3] - src[Mj3];
H1 = h1 * h1;
S1 = s1 * s1;
V1 = v1 * v1;
d1 = sqrt(V1 + S1 + H1);
rate1 = rate1 + src[Mi0] * src[Mj0] * (1 - d1 / sqrt(5.0));
h2 = dst[Mi2] * sin(dst[Mi1] / 180 * PI) - dst[Mj2] * sin(dst[Mj1] / 180 * PI);
s2 = dst[Mi2] * cos(dst[Mi1] / 180 * PI) - dst[Mj2] * cos(dst[Mj1] / 180 * PI);
v2 = dst[Mi3] - dst[Mj3];
H2 = h2 * h2;
S2 = s2 * s2;
V2 = v2 * v2;
d2 = sqrt(V2 + S2 + H2);
rate2 = rate2 + dst[Mi0] * dst[Mj0] * (1 - d2 / sqrt(5.0));
h3 = src[Mi2] * sin(src[Mi1] / 180 * PI) - dst[Mj2] * sin(dst[Mj1] / 180 * PI);
s3 = src[Mi2] * cos(src[Mi1] / 180 * PI) - dst[Mj2] * cos(dst[Mj1] / 180 * PI);
v3 = src[Mi3] - dst[Mj3];
H3 = h3 * h3;
S3 = s3 * s3;
V3 = v3 * v3;
d3 = sqrt(V3 + S3 + H3);
rate3 = rate3 + src[Mi0] * dst[Mj0] * (1 - d3 / sqrt(5.0));
}
}
rate = rate1 + rate2 - 2 * rate3;
return rate;
}
void main()
{
double src1[32] = {0};
double dst1[32] = {0};
int x, y;
double min_rate;
src = cvLoadImage("temp.bmp", 1);
IplImage *dst = cvLoadImage("temp1.bmp", 1);
if(!src)
{
printf("Load the image error!\n");
return;
}
if(!dst)
{
printf("Load the image error!\n");
return;
}
CvRect rect;
cvNamedWindow("SRC", 1);
cvShowImage("SRC", src);
img = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
cvSetMouseCallback("SRC", on_mouse, 0);
while(1)
{
int c = cvWaitKey(0);
if(c == 13)
{
rect = cvRect(min(pt_beg.x, pt_end.x), min(pt_beg.y, pt_end.y), abs(pt_end.x - pt_beg.x), abs(pt_end.y - pt_beg.y));
break;
}
}
printf("(x = %d, y = %d)\n", rect.x, rect.y);
cvSetImageROI(src, rect);
IplImage *temp = cvCreateImage(cvSize(rect.width, rect.height), src->depth, src->nChannels);
cvCopyImage(src, temp);
cvResetImageROI(src);
cal_DCD(temp, src1);
for(int i = 0; i < dst->height - rect.height; i++)
{
for(int j = 0; j < dst->width - rect.width; j++)
{
memset(dst1, 0, sizeof(dst1));
CvRect t_rect = cvRect(j, i, rect.width, rect.height);
IplImage *t_image = cvCreateImage(cvSize(rect.width, rect.height), dst->depth, dst->nChannels);
cvSetImageROI(dst, t_rect);
cvCopyImage(dst, t_image);
cal_DCD(t_image, dst1);
double total = computeD(src1, dst1);
printf("--%f--", total);
if(i == 0 && j == 0)
{
min_rate = total;
x = j;
y = i;
}
if(min_rate > total)
{
min_rate = total;
x = j;
y = i;
}
cvResetImageROI(dst);
cvReleaseImage(&t_image);
}
}
printf("\n--%f--(x = %d, y = %d)\n", min_rate, x, y);
cvDrawRect(dst, cvPoint(x, y), cvPoint(x + rect.width, y + rect.height), CV_RGB(255, 0, 255), 1, 8, 0);
cvNamedWindow("DST", 1);
cvShowImage("DST", dst);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&dst);
cvDestroyAllWindows();
}