#include<opencv2/opencv.hpp>
using namespace cv;
#define EXPORT_API __declspec(dllexport)
int m_width = 640;
int m_height = 480;
VideoCapture my_camera;
Mat temp, my_frameBGR;
Mat background;
int count = 0;
int T1 = 0, T2 = 0, T3 = 0;
Mat ProjectorPic, ProjectorPicA, ProjectorPicB;
Mat ProjectorGood;
extern "C" __declspec(dllexport)
double ComputPerFrame_From_Unity(void* image_data)
{
Mat image(480, 640, CV_8UC3);
memcpy(image.data, image_data, m_width * m_height * 3 * sizeof(uchar));
cvtColor(image, image, CV_BGR2RGB);
flip(image, image, 1);
flip(image, image, -1);
//imshow("虚拟相机", image);
if (image.data)
{
ProjectorPic = image.clone();
ProjectorPicA = image.clone();
ProjectorPicB = image.clone();
image.copyTo(ProjectorGood);
}
else
{
return 1;
}
}
Mat MoveDetect(Mat background, Mat tex)
{
//将background和img转为灰度图
Mat result = tex.clone();
Mat gray1, gray2;
cvtColor(background, gray1, CV_BGR2GRAY);
cvtColor(tex, gray2, CV_BGR2GRAY);
//进行canny边缘检测
Canny(background, background, 0, 30, 3);
//将background和img做差;对差值图diff进行阈值化处理
Mat diff;
absdiff(gray1, gray2, diff);
threshold(diff, diff, 50, 255, CV_THRESH_BINARY);
//二值化后使用中值滤波+膨胀
Mat element = getStructuringElement(MORPH_RECT, Size(11, 11));
medianBlur(diff, diff, 5); //中值滤波
dilate(diff, diff, element);
//查找并绘制轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(diff, contours, hierarcy, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE); //查找轮廓
vector<Rect> boundRect(contours.size()); //定义外接矩形集合
//查找正外接矩形
int x0 = 0, y0 = 0, w0 = 0, h0 = 0;
int x1, x2, y1, y2;
Mat ProjectorPicBROI;
Rect rect;
Mat CameraPicMask, CameraImg, ProjectorPicMask, ProjectorImg;
if (contours.size() == 0)
{
if (ProjectorPicA.empty())
{
return result;
}
else
{
ProjectorPicBROI = ProjectorPicA(Rect(Point(x0, y0), Point(x0 + ProjectorPicA.cols, y0 + ProjectorPicA.rows)));
ProjectorPicBROI = { Scalar(0, 0, 0) };
Point Pos1(10, 40);
putText(ProjectorPicB, "M16 装配", Pos1, CV_FONT_HERSHEY_COMPLEX, 0.8f, Scalar(0, 255, 255), 2);
Point Pos2(10, 100);
putText(ProjectorPicB, "M18 装配", Pos2, CV_FONT_HERSHEY_COMPLEX, 0.8f, Scalar(0, 255, 255), 2);
Point Pos3(10, 160);
putText(ProjectorPicB, "M20 装配", Pos3, CV_FONT_HERSHEY_COMPLEX, 0.8f, Scalar(0, 255, 255), 2);
imshow("ProjectorImgB", ProjectorPicA);
imshow("ProjectorImgA", ProjectorPicB);
}
}
else
{
for (int i = 0; i < contours.size(); i++)
{
boundRect[i] = boundingRect((Mat)contours[i]); //查找每个轮廓的外接矩形
x0 = boundRect[i].x;
y0 = boundRect[i].y;
w0 = boundRect[i].width;
h0 = boundRect[i].height;
if (10 < x0 && (x0 + w0) < 630 && 10 < y0 && (y0 + h0) < 470)
{
x1 = x0 - 10;
x2 = x0 + w0 + 10;
y1 = y0 - 10;
y2 = y0 + h0 + 10;
rect = Rect(Point(x1, y1), Point(x2, y2));
}
else
{
rect = Rect(Point(x0, y0), Point(x0 + w0, y0 + h0));
}
double Area = contourArea(contours[i]); //计算第i个轮廓的面积
if (w0 > 50 && h0 > 50)
{
//ProjectorPic = imread("F:\\Unity\\Unity工程\\534TTest\\Assets\\Textures\\0003.jpeg");
rectangle(result, Point(x0, y0), Point(x0 + w0, y0 + h0), Scalar(255, 255, 255), 0.5, 8); //绘制第i个外接矩形
rectangle(ProjectorPic, Point(x0, y0), Point(x0 + w0, y0 + h0), Scalar(255, 255, 255), 0.1, 8);
ProjectorPic(Rect(Point(x0, y0), Point(x0 + w0, y0 + h0))).setTo(0);
imshow("ProjectorImgA", ProjectorPic);
/*CameraPicMask = Mat::zeros(my_frameBGR.size(), CV_8UC1);
Rect rect = Rect(Point(x0, y0), Point(x0 + w0, y0 + h0));
CameraPicMask(rect).setTo(255);
my_frameBGR.copyTo(CameraImg, CameraPicMask);
imshow("CameraImgB", CameraImg);
imshow("CameraPicMask", CameraPicMask);*/
ProjectorPicMask = Mat::zeros(ProjectorPic.size(), CV_8UC3);
ProjectorPicMask(rect).setTo(255);
ProjectorGood.copyTo(ProjectorImg, ProjectorPicMask);
imshow("ProjectorImgB", ProjectorImg);
//imshow("ProjectorPicMask", ProjectorPicMask);
/
/*ProjectorPicMask = Mat::zeros(ProjectorPic.size(), CV_8UC3);
ProjectorPicMask(rect).setTo(255);
ProjectorGood.copyTo(ProjectorImg, ProjectorPicMask);
imshow("ProjectorImgB", ProjectorImg);
imshow("ProjectorPicMask", ProjectorPicMask);*/
/
}
Point ButtonPosition01(10, 40);
Point ButtonPosition02(10, 100);
Point ButtonPosition03(10, 160);
if (10 < x0 < 70)
{
if (10 < y0 && y0 < 50)
{
T1 = 1;
putText(result, "M16ButtonClicked", ButtonPosition01, CV_FONT_HERSHEY_SIMPLEX, 0.8f, Scalar(0, 255, 0), 2);
}
else
{
T1 = 0;
}
if (70 < y0 && y0 < 110)
{
T2 = 1;
}
else
{
T2 = 0;
}
if (130 < y0 && y0 < 170)
{
T3 = 1;
}
else
{
T3 = 0;
}
}
}
}
return result;
}
extern "C" bool EXPORT_API openCamera()
{
bool my_open = false;
while (!my_camera.isOpened())
{
//std::cout << "Cannot open the camera!" << std::endl;
my_camera.open(0);
}
my_camera.set(CV_CAP_PROP_FRAME_WIDTH, m_width);
my_camera.set(CV_CAP_PROP_FRAME_HEIGHT, m_height);
if (my_camera.isOpened())
{
my_open = true;
}
return my_open;
}
extern "C" void EXPORT_API recieveFrame(uchar* texturePtr)
{
Mat my_frameBGR;
Mat my_frameRBG;
Mat result;
my_camera >> my_frameBGR;
if (my_frameBGR.data)
{
cvtColor(my_frameBGR, my_frameRBG, CV_BGR2RGB);
memcpy(texturePtr, my_frameRBG.data, my_frameRBG.cols*my_frameRBG.rows*my_frameRBG.channels()*sizeof(uchar));
count++;
if (count == 1)
/*background = my_frameBGR.clone();
result = MoveDetect(background, my_frameBGR);*/
result = MoveDetect(my_frameBGR, my_frameBGR);
else
result = MoveDetect(temp, my_frameBGR);
temp = my_frameBGR.clone();
imshow("CameraImg", result);
}
}
extern "C" bool EXPORT_API num01()
{
if (T1 != 0)
{
T1 = 0;
return true;
}
else
{
return false;
}
}
extern "C" bool EXPORT_API num02()
{
if (T2 != 0)
{
T2 = 0;
return true;
}
else
{
return false;
}
}
extern "C" bool EXPORT_API num03()
{
if (T3 != 0)
{
T3 = 0;
return true;
}
else
{
return false;
}
}
extern "C" void EXPORT_API Quit()
{
destroyAllWindows();
my_camera.release();
}