#include "sharedmatting.h"
#include <time.h>
SharedMatting::SharedMatting()
{
kI = 10;
kC = 5.0;
kG = 4;
uT.clear();
tuples.clear();
}
SharedMatting::~SharedMatting()
{
cvReleaseImage(&pImg);
cvReleaseImage(&trimap);
cvReleaseImage(&matte);
uT.clear();
tuples.clear();
ftuples.clear();
for (int i = 0; i < height; ++i)
{
delete[] tri[i];
delete[] unknownIndex[i];
delete[] alpha[i];
}
delete[] tri;
delete[] unknownIndex;
delete[] alpha;
}
void SharedMatting::loadImage(char * filename)
{
pImg = cvLoadImage(filename);
if (!pImg)
{
cout << "Loading Image Failed!" << endl;
exit(-1);
}
height = pImg->height;
width = pImg->width;
step = pImg->widthStep;
channels = pImg->nChannels;
data = (uchar *)pImg->imageData;
unknownIndex = new int*[height];
tri = new int*[height];
alpha = new int*[height];
for(int i = 0; i < height; ++i)
{
unknownIndex[i] = new int[width];
tri[i] = new int[width];
alpha[i] = new int[width];
}
matte = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
}
void SharedMatting::loadTrimap(char * filename)
{
trimap = cvLoadImage(filename);
if (!trimap)
{
cout << "Loading Trimap Failed!" << endl;
exit(-1);
}
/*cvNamedWindow("aa");
cvShowImage("aa", trimap);
cvWaitKey(0);*/
}
void SharedMatting::expandKnown()
{
vector<struct labelPoint> vp;
int kc2 = kC * kC;
vp.clear();
int s = trimap->widthStep;
int c = trimap->nChannels;
uchar * d = (uchar *)trimap->imageData;
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < width; ++j)
{
tri[i][j] = d[i * step + j * channels];
}
}
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < width; ++j)
{
if (tri[i][j] != 0 && tri[i][j] != 255)
{
int label = -1;
double dmin = 10000.0;
bool flag = false;
int pb = data[i * step + j * channels];
int pg = data[i * step + j * channels + 1];
int pr = data[i * step + j * channels + 2];
CvScalar p = cvScalar(pb, pg, pr);
//int i1 = max(0, i - kI);
//int i2 = min(i + kI, height - 1);
//int j1 = max(0, j - kI);
//int j2 = min(j + kI, width - 1);
//
//for (int k = i1; k <= i2; ++k)
//{
// for (int l = j1; l <= j2; ++l)
// {
// int temp = tri[k][l];
// if (temp != 0 && temp != 255)
// {
// continue;
// }
// double dis = dP(cvPoint(i, j), cvPoint(k, l));
// if (dis > dmin)
// {
// continue;
// }
//
// int qb = data[k * step + l * channels];
// int qg = data[k * step + l * channels + 1];
// int qr = data[k * step + l * channels + 2];
// CvScalar q = cvScalar(qb, qg, qr);
// double distanceColor = distanceColor2(p, q);
// if (distanceColor <= kc2)
// {
// dmin = dis;
// label = temp;
// }
// }
//}
for (int k = 0; (k <= kI) && !flag; ++k)
{
int k1 = max(0, i - k);
int k2 = min(i + k, height - 1);
int l1 = max(0, j - k);
int l2 = min(j + k, width - 1);
for (int l = k1; (l <= k2) && !flag; ++l)
{
double dis;
double gray;
gray = tri[l][l1];
if (gray == 0 || gray == 255)
{
dis = dP(cvPoint(i, j), cvPoint(l, l1));
if (dis > kI)
{
continue;
}
int qb = data[l * step + l1 * channels];
int qg = data[l * step + l1 * channels + 1];
int qr = data[l * step + l1 * channels + 2];
CvScalar q = cvScalar(qb, qg, qr);
double distanceColor = distanceColor2(p, q);
if (distanceColor <= kc2)
{
flag = true;
label = gray;
}
}
if (flag)
{
break;
}
gray = tri[l][l2];
if (gray == 0 || gray == 255)
{
dis = dP(cvPoint(i, j), cvPoint(l, l2));
if (dis > kI)
{
continue;
}
int qb = data[l * step + l2 * channels];
int qg = data[l * step + l2 * channels + 1];
int qr = data[l * step + l2 * channels + 2];
CvScalar q = cvScalar(qb, qg, qr);
double distanceColor = distanceColor2(p, q);
if (distanceColor <= kc2)
{
flag = true;
label = gray;
}
}
}
for (int l = l1; (l <= l2) && !flag; ++l)
{
double dis;
double gray;
gray = tri[k1][l];
if (gray == 0 || gray == 255)
{
dis = dP(cvPoint(i, j), cvPoint(k1, l));
if (dis > kI)
{
continue;
}
int qb = data[k1 * step + l * channels];
int qg = data[k1 * step + l * channels + 1];
int qr = data[k1 * step + l * channels + 2];
CvScalar q = cvScalar(qb, qg, qr);
double distanceColor = distanceColor2(p, q);
if (distanceColor <= kc2)
{
flag = true;
label = gray;
}
}
gray = tri[k2][l];
if (gray == 0 || gray == 255)
{
dis = dP(cvPoint(i, j), cvPoint(k2, l));
if (dis > kI)
{
continue;
}
int qb = data[k2 * step + l * channels];
int qg = data[k2 * step + l * channels + 1];
int qr = data[k2 * step + l * channels + 2];
CvScalar q = cvScalar(qb, qg, qr);
double distanceColor = distanceColor2(p, q);
if (distanceColor <= kc2)
{
flag = true;
label = gray;
}
}
}
}
if (label != -1)
{
struct labelPoint lp;
lp.x = i;
lp.y = j;
lp.label = label;
vp.push_back(lp);
}
else
{
CvPoint lp;
lp.x = i;
lp.y = j;
uT.push_back(lp);
}
}
}
}
vector<struct labelPoint>::iterator it;
for (it = vp.begin(); it != vp.end(); ++it)
{
int ti = it->x;
int tj = it->y;
int label = it->label;
//cvSet2D(trimap, ti, tj, cvScalarAll(label));
tri[ti][tj] = label;
}
vp.clear();
/*cvNamedWindow("trimap");
cvShowImage("trimap", trimap);
cvWaitKey(0);*/
}
double SharedMatting::comalpha(CvScalar c, CvScalar f, CvScalar b)
{
double alpha = ((c.val[0] - b.val[0]) * (f.val[0] - b.val[0]) +
(c.val[1] - b.val[1]) * (f.val[1] - b.val[1]) +
(c.val[2] - b.val[2]) * (f.val[2] - b.val[2]))
/ ((f.val[0] - b.val[0]) * (f.val[0] - b.val[0]) +
(f.val[1] - b.val[1]) * (f.val[1] - b.val[1]) +
(f.val[2] - b.val[2]) * (f.val[2] - b.val[2]) + 0.0000001);
return min(1.0, max(0.0, alpha));
}
double SharedMatting::mP(int i, int j, CvScalar f, CvScalar b)
{
int bc = data[i * step + j * channels];
int gc = data[i * step + j * channels + 1];
int rc = data[i * step + j * channels + 2];
CvScalar c = cvScalar(bc, gc, rc);
double alpha = comalpha(c, f, b);
double result = sqrt((c.val[0] - alpha * f.val[0] - (1 - alpha) * b.val[0]) * (c.val[0] - alpha * f.val[0] - (1 - alpha) * b.val[0]) +
(c.val[1] - alpha * f.val[1] - (1 - alpha) * b.val[1]) * (c.val[1] - alpha * f.val[1] - (1 - alpha) * b.val[1]) +
(c.val[2] - alpha * f.val[2] - (1 - alpha) * b.val[2]) * (c.val[2] - alpha * f.val[2] - (1 - alpha) * b.val[2]));
return result / 255.0;
}
double SharedMatting::nP(int i, int j, CvScalar f, CvScalar b)
{
int i1 = max(0, i - 1);
int i2 = min(i + 1, height - 1);
int j1 = max(0, j - 1);
int j2 = min(j + 1, width - 1);
double result = 0;
for (int k = i1; k <= i2; ++k)
{
for (int l = j1; l <= j2; ++l)
{
double m = mP(k, l, f, b);
result += m * m;
}
}
return result;
}
double SharedMatting::eP(int i1, int j1, int i2, int j2)
{
//int flagi = 1, flagj = 1;
double ci = i2 - i1;
double cj = j2 - j1;
double z = sqrt(
- 1
- 2
- 3
- 4
- 5
- 6
前往页