I've an object tracking program as below.The problem is I want to make it into The Main program as a thread to run both the Main program and this program parallel:
#include"sstream"
#include"ostream"
#include"string"
#include"opencv2/highgui.hpp"
#include"opencv2/opencv.hpp"
#include"stdio.h"
using namespace cv;
using namespace std;
int H_MIN = 0;
int H_MAX = 256;
int S_MIN = 0;
int S_MAX = 256;
int V_MIN = 0;
int V_MAX = 256;
const string windowName1 = "Original image";
const string windowName2 = "HSV image";
const string windowName3 = "Thresholded image";
const string windowName4 = "After Morphological Operations";
const string trackbarWindowName = "Trackbars";
const int FRAME_HEIGHT = 480;
const int FRAME_WIDTH = 640;
const int MAX_NUM_OBJECTS = 2;
const int MIN_OBJECT_AREA = 20 * 20;
const int MAX_OBJECT_AREA = 64 * 48 / 1.5;
double robotposx, robotposy ;
void on_trackbar(int, void*)
{
}
string intToString(int number) {
std::stringstream ss;
ss << number;
return ss.str();
}
void createTrackbars() {
namedWindow(trackbarWindowName, 0);
char TrackbarName[50];
sprintf_s(TrackbarName, "H_MIN", H_MIN);
sprintf_s(TrackbarName, "H_MAX", H_MAX);
sprintf_s(TrackbarName, "S_MIN", S_MIN);
sprintf_s(TrackbarName, "S_MAX", S_MAX);
sprintf_s(TrackbarName, "V_MIN", V_MIN);
sprintf_s(TrackbarName, "V_MAX", V_MAX);
trackbar is moved(eg.H_LOW),
createTrackbar("H_MIN", trackbarWindowName, &H_MIN, H_MAX, on_trackbar);
createTrackbar("H_MAX", trackbarWindowName, &H_MAX, H_MAX, on_trackbar);
createTrackbar("S_MIN", trackbarWindowName, &S_MIN, S_MAX, on_trackbar);
createTrackbar("S_MAX", trackbarWindowName, &S_MAX, S_MAX, on_trackbar);
createTrackbar("V_MIN", trackbarWindowName, &V_MIN, V_MAX, on_trackbar);
createTrackbar("V_MAX", trackbarWindowName, &V_MAX, V_MAX, on_trackbar);
}
void drawObject(int x, int y, Mat& frame) {
window!)
circle(frame, Point(x, y), 20, Scalar(0, 255, 0), 2);
if (y - 25 > 0)
line(frame, Point(x, y), Point(x, y - 25), Scalar(0, 255, 0), 2);
else line(frame, Point(x, y), Point(x, 0), Scalar(0, 255, 0), 2);
if (y + 25 < FRAME_HEIGHT)
line(frame, Point(x, y), Point(x, y + 25), Scalar(0, 255, 0), 2);
else line(frame, Point(x, y), Point(x, FRAME_HEIGHT), Scalar(0, 255, 0), 2);
if (x - 25 > 0)
line(frame, Point(x, y), Point(x - 25, y), Scalar(0, 255, 0), 2);
else line(frame, Point(x, y), Point(0, y), Scalar(0, 255, 0), 2);
if (x + 25 < FRAME_WIDTH)
line(frame, Point(x, y), Point(x + 25, y), Scalar(0, 255, 0), 2);
else line(frame, Point(x, y), Point(FRAME_WIDTH, y), Scalar(0, 255, 0), 2);
putText(frame, intToString(x) + "," + intToString(y), Point(x, y + 30), 1, 1,
Scalar(0, 255, 0), 2);
}
void morphOps(Mat& thresh) {
Mat erodeElement = getStructuringElement(MORPH_RECT, Size(8, 8));
Mat dilateElement = getStructuringElement(MORPH_RECT, Size(8, 8));
erode(thresh, thresh, erodeElement);
erode(thresh, thresh, erodeElement);
dilate(thresh, thresh, dilateElement);
dilate(thresh, thresh, dilateElement);
}
void trackFilteredObject(int& x, int& y, Mat threshold, Mat& cameraFeed) {
Mat temp;
threshold.copyTo(temp);
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(temp, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
double refArea = 0;
bool objectFound = false;
if (hierarchy.size() > 0) {
int numObjects = hierarchy.size();
if (numObjects < MAX_NUM_OBJECTS) {
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
Moments moment = moments((cv::Mat)contours[index]);
double area = moment.m00;
if (area > MIN_OBJECT_AREA && area<MAX_OBJECT_AREA && area>refArea) {
x = moment.m10 / area;
y = moment.m01 / area;
objectFound = true;
refArea = area;
}
else objectFound = false;
}
if (objectFound == true) {
putText(cameraFeed, "Tracking Object", Point(0, 50), 2, 1, Scalar(0, 255, 0), 2);
drawObject(x, y, cameraFeed);
}
}
else putText(cameraFeed, "TOO MUCH NOISE! ADJUST FILTER", Point(0, 50), 1, 2,
Scalar(0, 0, 255), 2);
}
}
int main(int argc, char* argv[])
{
bool trackObjects = true;
bool useMorphOps = false;
int iLastX1 = -1;
int iLastY1 = -1;
int iLastX2 = -1;
int iLastY2 = -1;
Mat cameraFeed;
Mat HSV;
Mat threshold;
int x = 0, y = 0;
createTrackbars();
VideoCapture capture;
capture.open(0);
capture.set(cv::CAP_PROP_FRAME_WIDTH, FRAME_WIDTH);
capture.set(cv::CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT);
Mat imgTmp1; capture.read(imgTmp1);
Mat imgLines1 = Mat::zeros(imgTmp1.size(), CV_8UC3);;
Moments oMoments1 = moments(threshold);
double d1M01 = oMoments1.m01;
double d1M10 = oMoments1.m10;
double d1Area = oMoments1.m00;
double Xa = 22957,Ya = 17037, xa = 526, ya = 246;
double Xb = 22957, Yb = 2437, xb = 123, yb = 246;
double Xd = 12356, Yd = 17037, xd = 590, yd = 0;
double Xe = 22957, Ye = 9437, xe = 315, ye = 0;
double aw = -0.260163;
double bw = 275.0;
double c = 1057.03;
double a = -2.70684e-8;
double b = -6.11588e-4;
while (1) {
capture.read(cameraFeed);
cvtColor(cameraFeed, HSV, COLOR_BGR2HSV);
inRange(HSV, Scalar(H_MIN, S_MIN, V_MIN), Scalar(H_MAX, S_MAX, V_MAX), threshold);
if (useMorphOps)
morphOps(threshold);
if (trackObjects)
trackFilteredObject(x, y, threshold, cameraFeed);
Moments oMoments1 = moments(threshold);
double d1M01 = oMoments1.m01;
double d1M10 = oMoments1.m10;
double d1Area = oMoments1.m00;
if (d1Area > 10000)
{
int posX1 = d1M10 / d1Area;
int posY1 = d1M01 / d1Area;
if ( posX1 >= 0 && posY1 >= 0)
{
robotposx = (1.0 / (posY1 - c) - b) / a;
robotposy = (posX1 - xe) * (Yd - Ye) / (aw * posY1 + bw) + Ye;
line(threshold, Point(posX1-10, posY1), Point(posX1+10, posY1), Scalar(255, 0,
0), 2);
line(threshold, Point(posX1 , posY1-10), Point(posX1, posY1+10), Scalar(255, 0,
0), 2);
}
iLastX1 = posX1;
iLastY1 = posY1;
vector<vector<cv::Point>> contours;
findContours(threshold, contours, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
for (int i = 0; i < contours.size(); i++)
{
drawContours(threshold, contours, i, Scalar(255, 0, 0), 2);
}
imshow(windowName3, threshold);
imshow(windowName1, cameraFeed);
imshow(windowName2, HSV);
waitKey(1);
}
}
return 0;
}
What I have tried:
I've put the part in
int main(int argc, char* argv[]) into The Main program and create the thread by lambda expression like this but the program didn't run at all(maybe it was heavy and can not load)
int main(int argc, char* argv[])
{
bool trackObjects = true;
bool useMorphOps = false;
int iLastX1 = -1;
int iLastY1 = -1;
int iLastX2 = -1;
int iLastY2 = -1;
Mat cameraFeed;
Mat HSV;
Mat threshold;
int x = 0, y = 0;
createTrackbars();
VideoCapture capture;
capture.open(0);
capture.set(cv::CAP_PROP_FRAME_WIDTH, FRAME_WIDTH);
capture.set(cv::CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT);
Mat imgTmp1; capture.read(imgTmp1);
Mat imgLines1 = Mat::zeros(imgTmp1.size(), CV_8UC3);;
Moments oMoments1 = moments(threshold);
double d1M01 = oMoments1.m01;
double d1M10 = oMoments1.m10;
double d1Area = oMoments1.m00;
double Xa = 22957, Ya = 17037, xa = 526, ya = 246;
double Xb = 22957, Yb = 2437, xb = 123, yb = 246;
double Xd = 12356, Yd = 17037, xd = 590, yd = 0;
double Xe = 22957, Ye = 9437, xe = 315, ye = 0;
double aw = -0.260163;
double bw = 275.0;
double c = 1057.03;
double a = -2.70684e-8;
double b = -6.11588e-4;
capture.read(cameraFeed);
cvtColor(cameraFeed, HSV, COLOR_BGR2HSV);
inRange(HSV, Scalar(H_MIN, S_MIN, V_MIN), Scalar(H_MAX, S_MAX, V_MAX), threshold);
if (useMorphOps)
morphOps(threshold);
if (trackObjects)
trackFilteredObject(x, y, threshold, cameraFeed);
if (d1Area > 10000)
{
int posX1 = d1M10 / d1Area;
int posY1 = d1M01 / d1Area;
if ( posX1 >= 0 && posY1 >= 0)
{
robotposx = (1.0 / (posY1 - c) - b) / a;
robotposy = (posX1 - xe) * (Yd - Ye) / (aw * posY1 + bw) + Ye;
line(threshold, Point(posX1 - 10, posY1), Point(posX1 + 10, posY1), Scalar(255, 0,
0), 2);
line(threshold, Point(posX1, posY1 - 10), Point(posX1, posY1 + 10), Scalar(255, 0,
0), 2);
}
iLastX1 = posX1;
iLastY1 = posY1;
vector<vector<cv::Point> > balls;
vector<cv::Rect> ballsBox;
vector<vector<cv::Point>> contours;
findContours(threshold, contours, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
std::thread t1([&]() {
for (int i = 0; i < contours.size(); i++)
{
drawContours(threshold, contours, i, Scalar(255, 0, 0), 2);
cv::Rect bBox;
bBox = cv::boundingRect(contours[i]);
float ratio = (float)bBox.width / (float)bBox.height;
if (ratio > 1.0f)
ratio = 1.0f / ratio;
if (ratio > 0.75 && bBox.area() >= 400)
{
balls.push_back(contours[i]);
ballsBox.push_back(bBox);
}
cv::Point center;
center.x = ballsBox[i].x + ballsBox[i].width / 2;
center.y = ballsBox[i].y + ballsBox[i].height / 2;
cv::circle(threshold, center, 2, CV_RGB(20, 150, 20), -1);
stringstream sstr;
sstr << "(" << center.x << "," << center.y << ")";
cv::putText(threshold, sstr.str(),
cv::Point(center.x + 3, center.y - 3),
cv::FONT_HERSHEY_SIMPLEX, 0.5, CV_RGB(20, 150, 20), 2);
}
});
t1.join();
imshow(windowName3, threshold);
imshow(windowName1, cameraFeed);
imshow(windowName2, HSV);
waitKey(10);
}
Thank you!