void FizSphere::compute() { /**computing masses of triangles copied from FizObject */ double integral[4] = {0.0, 0.0, 0.0, 0.0}; double f1x, f2x, f3x, g0x, g1x, g2x; double f1y, f2y, f3y, g0y, g1y, g2y; double f1z, f2z, f3z, g0z, g1z, g2z; point p0,p1,p2; for(int i = 0; i < vertices.size(); i++) { triangle& t = *(vertices[i]); sub_compute(t[0][0], t[1][0], t[2][0], f1x, f2x, f3x, g0x, g1x, g2x); sub_compute(t[0][1], t[1][1], t[2][1], f1y, f2y, f3y, g0y, g1y, g2y); sub_compute(t[0][2], t[1][2], t[2][2], f1z, f2z, f3z, g0z, g1z, g2z); const vec3& d = t.normal; t.massp = d[0] * f1x; integral[0] += d[0] * f1x; integral[1] += d[0] * f2x; integral[2] += d[1] * f2y; integral[3] += d[2] * f2z; } integral[0] *= div_consts[0]; integral[1] *= div_consts[1]; integral[2] *= div_consts[1]; integral[3] *= div_consts[1]; setProperty("temp_mass", fizdatum(getMass())); setMass(integral[0]); setPos(vec3(integral[1]/mass, integral[2]/mass, integral[3]/mass)); /**end copied code */ std::vector<double> tempI(6,0.0); std::vector<double> tempIi(6,0.0); tempI[0] = tempI[1] = tempI[2] = 2/5.*getProperty("temp_mass").scalar/pow(radius,2); tempI[4] = tempI[5] = tempI[3] = 0; tempIi[0] = tempIi[1] = tempIi [2] = 1./tempI[0]; tempIi[3] = tempIi[4] = tempIi[5] = 0; setInertiaTensor(tempI); setInertiaTensorInv(tempIi); }
std::vector<std::vector<std::vector<cv::Point>>> MultiContourObjectDetector::findApproxContours( cv::Mat image, bool performOpening, bool findBaseShape) { // CREATE ACTIVE ZONE 80% AND 50% --------------------- Point centre(image.size().width / 2, image.size().height / 2); int deleteHeight = image.size().height * _deleteFocus; int deleteWidth = image.size().width * _deleteFocus; int deleteX = centre.x - deleteWidth / 2; int deleteY = centre.y - deleteHeight / 2; int attenuationHeight = image.size().height * _attenuationFocus; int attenuationWidth = image.size().width * _attenuationFocus; int attenuationX = centre.x - attenuationWidth / 2; int attenuationY = centre.y - attenuationHeight / 2; Rect erase(deleteX, deleteY, deleteWidth, deleteHeight); _deleteRect = erase; Rect ease(attenuationX, attenuationY, attenuationWidth, attenuationHeight); _attenuationRect = ease; // ---------------------------------------- bool imageTooBig = false; Mat newImage; if (image.size().height <= 400 || image.size().width <= 400) { Mat pickColor = image(Rect((image.size().width / 2) - 1, image.size().height - 2, 2, 2)); Scalar color = mean(pickColor); int increment = 2; newImage = Mat(Size(image.size().width + increment, image.size().height + increment), image.type()); newImage = color; Point nc(newImage.size().width / 2, newImage.size().height / 2); int incH = image.size().height; int incW = image.size().width; int incX = nc.x - incW / 2; int incY = nc.y - incH / 2; image.copyTo(newImage(Rect(incX, incY, incW, incH))); } else { imageTooBig = true; newImage = image; } Size imgSize = newImage.size(); Mat gray(imgSize, CV_8UC1); Mat thresh(imgSize, CV_8UC1); if (newImage.channels() >= 3) cvtColor(newImage, gray, CV_BGR2GRAY); else newImage.copyTo(gray); int minThreshold; if (performOpening) { // PERFORM OPENING (Erosion --> Dilation) int erosion_size = 3; int dilation_size = 3; if (imageTooBig) { erosion_size = 5; dilation_size = 5; } Mat element = getStructuringElement(0, Size(2 * erosion_size, 2 * erosion_size), Point(erosion_size, erosion_size)); erode(gray, gray, element); dilate(gray, gray, element); minThreshold = mean(gray)[0]; if (minThreshold < 90) minThreshold = 60; else if (minThreshold >= 90 && minThreshold < 125) minThreshold = 100; } threshold(gray, thresh, minThreshold, 255, THRESH_BINARY); #ifdef DEBUG_MODE imshow("Threshold", thresh); #endif vector<vector<Point>> contours; vector<Vec4i> hierarchy; vector<Point> hull, approx; map<int, vector<vector<Point>>> hierachedContours; map<int, vector<vector<Point>>> approxHContours; findContours(thresh, contours, hierarchy, CV_RETR_TREE, CHAIN_APPROX_NONE); #ifdef DEBUG_MODE Mat tempI(image.size(), CV_8UC1); tempI = Scalar(0); drawContours(tempI, contours, -1, cv::Scalar(255), 1, CV_AA); imshow("Contours", tempI); #endif vector<vector<Point>> temp; // CATALOG BY HIERARCHY LOOP for (int i = 0; i < contours.size(); i++) { #ifdef DEBUG_MODE tempI = Scalar(0); temp.clear(); temp.push_back(contours[i]); drawContours(tempI, temp, -1, cv::Scalar(255), 1, CV_AA); #endif int parent = hierarchy[i][3]; if (parent == -1) { if (hierachedContours.count(i) == 0) { // me not found hierachedContours.insert(pair<int, vector<vector<Point>>>(i, vector<vector<Point>>())); hierachedContours[i].push_back(contours[i]); } else { // me found continue; } } else { if (hierachedContours.count(parent) == 0) { // dad not found hierachedContours.insert(pair<int, vector<vector<Point>>>(parent, vector<vector<Point>>())); hierachedContours[parent].push_back(contours[parent]); } hierachedContours[parent].push_back(contours[i]); } } int minPoint, maxPoint; minPoint = _minContourPoints - _minContourPoints / 2.1; maxPoint = _minContourPoints + _minContourPoints / 1.5; // APPROX LOOP for (map<int, vector<vector<Point>>>::iterator it = hierachedContours.begin(); it != hierachedContours.end(); it++) { if (it->second[0].size() < 400) continue; #ifdef DEBUG_MODE tempI = Scalar(0); drawContours(tempI, it->second, -1, cv::Scalar(255), 1, CV_AA); #endif if (it == hierachedContours.begin() && it->second.size() < _aspectedContours) continue; for (int k = 0; k < it->second.size(); k++) { if (it->second[k].size() < _minContourPoints) { if (k == 0) // padre break; else // figlio continue; } convexHull(it->second[k], hull, false); double epsilon = it->second[k].size() * 0.003; approxPolyDP(it->second[k], approx, epsilon, true); #ifdef DEBUG_MODE tempI = Scalar(0); vector<vector<Point>> temp; temp.push_back(approx); drawContours(tempI, temp, -1, cv::Scalar(255), 1, CV_AA); #endif // REMOVE TOO EXTERNAL SHAPES ------------- if (imageTooBig) { Rect bounding = boundingRect(it->second[k]); #ifdef DEBUG_MODE rectangle(tempI, _deleteRect, Scalar(255)); rectangle(tempI, bounding, Scalar(255)); #endif bool isInternal = bounding.x > _deleteRect.x && bounding.y > _deleteRect.y && bounding.x + bounding.width < _deleteRect.x + _deleteRect.width && bounding.y + bounding.height < _deleteRect.y + _deleteRect.height; if (!isInternal) { if (k == 0) break; } } // -------------------------------------------------- if (!findBaseShape) { if (hull.size() < minPoint || hull.size() > maxPoint) { if (k == 0) // padre break; else // figlio continue; } } if (k == 0) { approxHContours.insert(pair<int, vector<vector<Point>>>(it->first, vector<vector<Point>>())); approxHContours.at(it->first).push_back(approx); } else { approxHContours[it->first].push_back(approx); } } } int maxSize = 0, maxID = 0; vector<vector<vector<Point>>> lookupVector; for (map<int, vector<vector<Point>>>::iterator it = approxHContours.begin(); it != approxHContours.end(); it++) { if (it->second.size() <= 1) continue; if (findBaseShape) { int totSize = 0; for (int k = 0; k < it->second.size(); k++) { totSize += it->second[k].size(); } if (totSize > maxSize) { maxSize = totSize; maxID = it->first; } } else { lookupVector.push_back(it->second); } } if (findBaseShape) { lookupVector.push_back(approxHContours.at(maxID)); } return lookupVector; }
std::vector<std::vector<std::vector<cv::Point>>> MultiContourObjectDetector::processContours( std::vector<std::vector<std::vector<cv::Point>>> approxContours, double hammingThreshold, double correlationThreshold, int* numberOfObject) { vector<vector<vector<Point>>> objects; double attenuation = 0; for (int i = 0; i < approxContours.size(); i++) { if (approxContours[i].size() != _baseShape.size()) continue; attenuation = 0; #ifdef DEBUG_MODE Mat tempI(Size(1000, 1000), CV_8UC1); tempI = Scalar(0); drawContours(tempI, approxContours[i], -1, cv::Scalar(255), 1, CV_AA); #endif double totCorrelation = 0, totHamming = 0; Moments m = moments(approxContours[i][0], true); int cx = int(m.m10 / m.m00); int cy = int(m.m01 / m.m00); Point c(cx, cy); if (!(c.x >= _attenuationRect.x && c.y >= _attenuationRect.y && c.x <= (_attenuationRect.x + _attenuationRect.width) && c.y <= (_attenuationRect.y + _attenuationRect.height))) attenuation = 5; // C and H with external contour vector<Point> externalKeypoints; Utility::findCentroidsKeypoints(approxContours[i][0], externalKeypoints, Utility::CentroidDetectionMode::THREE_LOOP); totCorrelation += (Utility::correlationWithBase(externalKeypoints, _baseKeypoints[0]) - attenuation); totHamming += (Utility::calculateContourPercentageCompatibility(approxContours[i][0], _baseShape[0]) - attenuation); // looking for the contour with the better cnetroids and shape match for (int j = 1; j < approxContours[i].size(); j++) { attenuation = 0; Moments m = moments(approxContours[i][j], true); int cx = int(m.m10 / m.m00); int cy = int(m.m01 / m.m00); Point c(cx, cy); if (!(c.x >= _attenuationRect.x && c.y >= _attenuationRect.y && c.x <= (_attenuationRect.x + _attenuationRect.width) && c.y <= (_attenuationRect.y + _attenuationRect.height))) attenuation = 5; double maxCorrelation = std::numeric_limits<double>::min(), maxHamming = std::numeric_limits<double>::min(); for (int k = 1; k < _baseShape.size(); k++) { vector<Point> internalKeypoints; Utility::findCentroidsKeypoints(approxContours[i][j], internalKeypoints, Utility::CentroidDetectionMode::THREE_LOOP); maxCorrelation = max(maxCorrelation, Utility::correlationWithBase(internalKeypoints, _baseKeypoints[k])); maxHamming = max(maxHamming, Utility::calculateContourPercentageCompatibility(approxContours[i][j], _baseShape[k])); } totCorrelation += (maxCorrelation - attenuation); totHamming += (maxHamming - attenuation); } totCorrelation /= approxContours[i].size(); totHamming /= approxContours[i].size(); cout << "Middle Correlation " << to_string(i) << " with base ---> " << totCorrelation << endl; cout << "Middle Hamming distance" << to_string(i) << " with base ---> " << totHamming << endl; if (totCorrelation >= correlationThreshold && totHamming >= hammingThreshold) objects.push_back(approxContours[i]); } *numberOfObject = objects.size(); return objects; }