#include "shadow.h"
Mat shadowbackimg;
int thresh1(120);
int thresh2(120);
int thresh3(2);
int ab1(1);
int ab2(6);
int ab3(12);
int lingthresh3(30);
/*视频HSV去阴影处理*/
void sobel(Mat &src, Mat &mag)
{
Mat foreandx;
Mat foreandy;
Sobel(src, foreandx, CV_16S, 1, 0,-1);
Sobel(src, foreandy, CV_16S, 0, 1, -1);
convertScaleAbs(foreandx, foreandx); //将CV_16S转为CV_8U
convertScaleAbs(foreandy, foreandy);
addWeighted(foreandy, 0.5, foreandx, 0.5, 0, mag); //将两图相加
}
void gradientGray(Mat &src, Mat &mag)
{
typedef unsigned char byte;
const int H = src.rows, W = src.cols;
Mat Ix(H, W, CV_32S), Iy(H, W, CV_32S);
Mat Ix2(H, W, CV_32S), Iy2(H, W, CV_32S);
//因为计算出的梯度值可能有正有负,且值也可能会很大,故数据类型为整形
// 求水平方向梯度,处理左右边缘像素
for (int y = 1; y < W; y++)
{
for (int x = 1; x < H; x++)
{
Ix.at<int>(x, y) = abs(src.at<byte>(x, y) - src.at<byte>(x-1,y));
}
//Ix.at<int>(0, y) = abs(src.at<byte>(1, y) - src.at<byte>(0, y));
}
for (int x = 1; x <H; x++)
{
for (int y = 1; y < W; y++)
{
Ix2.at<int>(x, y) = abs(src.at<byte>(x, y) - src.at<byte>(x , y-1));
}
//Ix2.at<int>(x, 0) = abs(src.at<byte>(x, 1) - src.at<byte>(x,0));
}
// 求垂直方向梯度,处理左右边缘像素
for (int x = 1; x < H; x++)
{
for (int y = 1; y < W; y++)
{
Iy.at<int>(x,y) = abs(src.at<byte>(x,y-1) - src.at<byte>(x-1,y));
}
}
for (int x = 1; x < H; x++)
{
for (int y = 1; y < W; y++)
{
Iy2.at<int>(x, y) = abs(src.at<byte>(x, y ) - src.at<byte>(x - 1, y-1));
}
}
convertScaleAbs(min(Ix + Iy+ Ix2 + Iy2, 255), mag); //这句话和上面的for循环是同样的功能
}
/*SOBEL算子处理阴影*/
void shadow3(const Mat backframe, const Mat foreframe, const Mat backseg)
{
Mat backseg2;
backseg2 = backseg.clone();
Mat morphologyKernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
//medianBlur(segmentationMap, segmentationMap,3); /* 3x3 median filtering */
morphologyEx(backseg2, backseg2, MORPH_CLOSE, morphologyKernel, Point(-1, -1), 2, BORDER_REPLICATE);
//morphologyEx(backseg, backseg, MORPH_OPEN, morphologyKernel, Point(-1, -1), 2, BORDER_REPLICATE);
morphologyEx(backseg2, backseg2, MORPH_ERODE, morphologyKernel, Point(-1, -1), 1, BORDER_REPLICATE);
chao_fillHole(backseg2, backseg2);
//imshow("原back", backseg2);
typedef unsigned char byte;
CvCapture* pCapture = NULL;
CvCapture* pCapture2 = NULL;
IplImage* pRetImg = NULL;
IplImage* pRetImg2 = NULL;
IplImage* pBkImg = NULL;
IplImage* pFrImg = NULL;
IplImage* pFkHsv = NULL;
IplImage* pBkHsv = NULL;
Mat src;
Mat dst;
Mat src2;
Mat dst2;
Mat shadowimg2;
//Mat mat = cvarrToMat(image);
pBkImg = cvCloneImage(&(IplImage)backframe);
pFrImg = cvCloneImage(&(IplImage)foreframe);
//cvShowImage("pBkImg", pBkImg);
//cvShowImage("pFrImg", pFrImg);
pBkHsv = cvCreateImage(cvSize(pBkImg->width, pBkImg->height), IPL_DEPTH_8U, 3);
pFkHsv = cvCreateImage(cvSize(pFrImg->width, pFrImg->height), IPL_DEPTH_8U, 3);
pRetImg = cvCreateImage(cvSize(pFrImg->width, pFrImg->height), IPL_DEPTH_8U, 1);
pRetImg2 = cvCreateImage(cvSize(pFrImg->width, pFrImg->height), IPL_DEPTH_8U, 3);
int step = pFrImg->widthStep / sizeof(uchar);
int step2 = pRetImg->widthStep / sizeof(uchar);
int channels = pFrImg->nChannels;
shadowimg2 = backseg2.clone();
pRetImg = cvCloneImage(&(IplImage)shadowimg2);
/*将backseg2转换为3通道的backimg3*/
vector<Mat> mbgr(3);
Mat backimg3(backseg2.size(), CV_8UC3);
mbgr[0] = backseg2;
mbgr[1] = backseg2;
mbgr[2] = backseg2;
merge(mbgr, backimg3);
Mat backand;
Mat foreand;
bitwise_and(backimg3, foreframe, foreand);
bitwise_and(backimg3, backframe, backand);
morphologyKernel = getStructuringElement(MORPH_RECT, Size(1, 3), Point(-1, -1));
morphologyEx(backseg2, backseg2, MORPH_CLOSE, morphologyKernel, Point(-1, -1), 3, BORDER_REPLICATE);
chao_fillHole(backseg2, backseg2);
Mat tmpbackseg2 = backseg2.clone();
morphologyEx(backseg2, backseg2, MORPH_DILATE, morphologyKernel, Point(-1, -1), 2, BORDER_REPLICATE);
morphologyEx(backseg2, backseg2, MORPH_ERODE, morphologyKernel, Point(-1, -1), 1, BORDER_REPLICATE);
chao_fillHole(backseg2, backseg2);
// imshow("前景提取", foreand);
// imshow("相应背景", backand);
/*边缘检测*/
Mat grayforeand;
Mat graybackand;
Mat foreandx;
Mat foreandy;
Mat backandx;
Mat backandy;
cvtColor(backand, graybackand, CV_RGB2GRAY);
cvtColor(foreand, grayforeand, CV_RGB2GRAY);
sobel(grayforeand, foreandx);
// Sobel(grayforeand, foreandy, CV_16S, 0, 1, -1);
// convertScaleAbs(foreandx, foreandx); //将CV_16S转为CV_8U
// convertScaleAbs(foreandy, foreandy);
// addWeighted(foreandy, 0.5, foreandx, 0.5, 0, foreandx); //将两图相加
threshold(foreandx, dst, thresh2, 255, THRESH_BINARY);
//imshow("foredst", dst);
//imshow("grayforeand2", foreandx);
sobel(graybackand, backandx);
//Sobel(graybackand, backandx, CV_16S, 1, 0, -1);
//Sobel(graybackand, backandy, CV_16S, 0, 1, -1);
//convertScaleAbs(backandx, backandx); //将CV_16S转为CV_8U
//convertScaleAbs(backandy, backandy);
//addWeighted(backandx, 0.5, backandy, 0.5, 0, backandx); //将两图相加
threshold(backandx, dst2, thresh1, 255, THRESH_BINARY);
//imshow("backdst", dst2);
Mat absdst;
absdiff(dst2, dst, absdst);
convertScaleAbs(absdst, absdst);
bitwise_and(dst, absdst, absdst);
//imshow("absdst", absdst);
shadowbackimg = absdst.clone();
morphologyKernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(absdst, absdst, MORPH_OPEN, morphologyKernel, Point(-1, -1), 1, BORDER_REPLICATE);
morphologyKernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
morphologyEx(absdst, absdst, MORPH_CLOSE, morphologyKernel, Point(-1, -1), 3, BORDER_REPLICATE);
morphologyKernel = getStructuringElement(MORPH_RECT, Size(10, 10), Point(-1, -1));
morphologyEx(absdst, absdst, MORPH_DILATE, morphologyKernel, Point(-1, -1), 3, BORDER_REPLICATE);
morphologyEx(absdst, absdst, MORPH_ERODE, morphologyKernel, Point(-1, -1), 3, BORDER_REPLICATE);
chao_fillHole(absdst, absdst);
shadowbackimg = absdst.clone();
// imshow("sobel检测结果",absdst);
Mat backsegsobel;
bitwise_xor(shadowbackimg, backseg2, backsegsobel);
/*HSV检测*/
pBkImg = cvCloneImage(&(IplImage)backand);
pFrImg = cvCloneImage(&(IplImage)foreand);
cvCvtColor(pBkImg, pBkHsv, CV_BGR2HSV);
cvCvtColor(pFrImg, pFkHsv, CV_BGR2HSV);
double a, b, c, d;
for (int i = 0; i<pFkHsv->height; i++)
{
for (int j = 0; j<pFkHsv->width; j++)
{
if (pFrImg->imageData[i*step + j * 3 + 0] == 0 && pFrImg->imageData[i*step + j * 3 + 1] == 0 && pFrImg->imageData[i*step + j * 3 + 2] == 0)
{
pRetImg->imageData[i*step2 + j] = 0;
}
else
{
a = (double)(pFkHsv->imageData[i*step + j * 3 + 2]) / (pBkHsv->imageData[i*step + j * 3 + 2]);
b = (double)(pFkHsv->imageData[i*step + j * 3 + 2]) / (pBkHsv->imageData[i*step + j * 3 + 2]);
c = (double)abs(pFkHsv->imageData[i*step + j * 3 + 1] - pBkHsv->imageData[i*step + j * 3 + 1]);
d = (double)abs(pFkHsv->imageData[i*step + j * 3 + 0] - pBkHsv->imageData[i*step + j * 3 + 0]);
if ((a >= 0.15) && (b <= 0.3)
// &&(c <= 0.5*255) && (d <= 0.1*255)
)
{
pRetImg->imageData[i*step2 + j] = 255;
}
else
{
pRetImg->imageData[i*step2 + j] = 0;
}
}
}
}
//cvShowImage("pRetImg21", pRetImg);
shadowbackimg = cvarrToMat(pRetImg);
morphologyKernel = getStructuringElement(MORPH_RECT, Size(2, 2), Point(-1, -1));
morphologyEx(shadowbackimg, shadowbackimg, MORPH_OPEN, morphologyKernel, Point(-1, -1), 1, BORDER_REPLICATE);
morphologyKernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
morphologyEx(shadowbackimg, shadowbackimg, MORPH_CLOSE, morphologyKernel, Point(-1