32 #include <Image/ImageProcessor.h>
33 #include <pcl/common/point_tests.h>
50 usingProxy(getProperty<std::string>(
"ViewSelectionName").getValue());
51 usingProxy(getProperty<std::string>(
"RobotStateComponentName").getValue());
53 providerName = getProperty<std::string>(
"providerName").getValue();
54 usingImageProvider(providerName);
55 usingPointCloudProvider(providerName);
57 std::string graphFileName =
"RobotAPI/ViewSelection/graph40k.gra";
65 ARMARX_VERBOSE <<
"Created egosphere graph with " << saliencyEgosphereGraph->getNodes()->size() <<
"nodes";
67 graphLookupTable->buildLookupTable(saliencyEgosphereGraph);
75 headFrameName = getProperty<std::string>(
"HeadFrameName").getValue();
77 hog->loadTrainingData(getProperty<std::string>(
"TrainingData").getValue());
78 hog->setParameters(
true,
true);
90 images =
new CByteImage*[numImages];
91 for (
int i = 0 ; i < numImages; i++)
97 result =
new CByteImage*[numResultImages];
98 result[0] = images[0];
103 visionx::ImageDimension dimension(images[0]->width, images[0]->height);
106 robotStateComponent = getProxy<RobotStateComponentInterfacePrx>(getProperty<std::string>(
"RobotStateComponentName").getValue());
110 viewSelection = getProxy<ViewSelectionInterfacePrx>(getProperty<std::string>(
"ViewSelectionName").getValue());
121 for (
int i = 0; i < numImages; i++)
127 for (
int i = 0; i < numResultImages; i++)
133 delete graphLookupTable;
134 delete saliencyEgosphereGraph;
142 std::lock_guard<std::mutex> lock(mutex);
144 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr currentPointCloud(
new pcl::PointCloud<pcl::PointXYZRGBA>());
149 if (!waitForImages(providerName))
156 if (!waitForPointClouds(providerName))
163 if (getImages(images) != numImages)
170 if (!getPointClouds(currentPointCloud))
179 saliencyEgosphereGraph->set(0.0);
181 const int scaleFactor = 4;
183 int width = images[0]->width / scaleFactor;
184 int height = images[0]->height / scaleFactor;
185 CByteImage* image =
new CByteImage(width, height, CByteImage::eRGB24);
186 ::ImageProcessor::Resize(images[0], image);
188 ARMARX_VERBOSE <<
"downscaling image to: " << width <<
"x" << height;
191 CFloatImage* saliencyImage =
new CFloatImage(width, height, 1);
197 hog->findSalientRegions(image, saliencyImage);
199 std::vector<cv::Point2f> points;
202 std::map<int, int> saliencyHist;
203 float priorityProcent = 0.9;
205 int intensityThreshold = 255;
207 int saliencyImageWidth = saliencyImage->width;
209 for (
int i = 0; i < saliencyImage->height; i++)
211 for (
int j = 0; j < saliencyImageWidth; j++)
213 saliencyHist[(int)(saliencyImage->pixels[i * saliencyImageWidth + j] * 255.0)]++;
218 int usefulSampleAmount = priorityProcent * (saliencyImage->width * saliencyImage->height - saliencyHist[0]);
219 for (
int i = 1; i <= 255; i++)
221 if (!saliencyHist.count(i))
225 saliencySum += saliencyHist[i];
226 if (saliencySum > usefulSampleAmount)
228 intensityThreshold = i;
233 for (
int i = 0; i < saliencyImage->height; i++)
235 for (
int j = 0; j < saliencyImageWidth; j++)
237 if (saliencyImage->pixels[i * saliencyImageWidth + j] * 255.0 > intensityThreshold)
239 points.push_back(cv::Point2f(j, i));
244 cv::Mat samples(points.size(), 2, CV_32F);
245 for (
size_t i = 0; i < points.size(); i++)
247 samples.at<
float>(i, 0) = points[i].x;
248 samples.at<
float>(i, 1) = points[i].y;
253 cv::kmeans(samples, clusterNum, outputLable, cv::TermCriteria(cv::TermCriteria::COUNT +
cv::TermCriteria::EPS, 20, 0.1), 10, cv::KMEANS_PP_CENTERS, centers);
257 std::map<int, int> numberOfEachCluster;
258 for (
int i = 0; i < samples.rows; i++)
260 numberOfEachCluster[outputLable.at<
int>(i, 0)]++;
262 size_t maxCluster = 0;
264 for (
size_t i = 0; i < numberOfEachCluster.size(); i++)
266 if (numberOfEachCluster[i] > numberOfEachCluster[maxCluster])
279 for (
size_t i = 0; i < numberOfEachCluster.size(); i++)
281 if ((i != maxCluster) && numberOfEachCluster[i] > numberOfEachCluster[secondCluster])
293 #pragma omp parallel for
294 for (
int i = 0; i < images[0]->height; i++)
296 for (
int j = 0; j < images[0]->width; j++)
298 int idx = i * images[0]->width + j;
300 float saliency = saliencyImage->pixels[(i / scaleFactor * width) + (j / scaleFactor)];
302 result[1]->pixels[3 * idx + 0] = 255 * saliency;
303 result[1]->pixels[3 * idx + 1] = 255 * saliency;
304 result[1]->pixels[3 * idx + 2] = 255 * saliency;
306 result[2]->pixels[3 * idx + 0] = (0.2 + 0.8 * saliency) * result[0]->pixels[3 * idx + 0];
307 result[2]->pixels[3 * idx + 1] = (0.2 + 0.8 * saliency) * result[0]->pixels[3 * idx + 1];
308 result[2]->pixels[3 * idx + 2] = (0.2 + 0.8 * saliency) * result[0]->pixels[3 * idx + 2];
375 for (
int i = 0; i < centers.rows; i++)
377 int downScaleIdx = ((int)centers.at<
float>(i, 1) * width) + ((
int)centers.at<
float>(i, 0));
378 int idx = (int)centers.at<
float>(i, 1) * scaleFactor * images[0]->width + (int)centers.at<
float>(i, 0) * scaleFactor;
380 float saliency = saliencyImage->pixels[downScaleIdx];
382 if (idx >= (
int)currentPointCloud->points.size())
387 Eigen::Vector3f vec = currentPointCloud->points[idx].getVector3fMap();
389 if (!pcl::isFinite(currentPointCloud->points[idx]))
396 currentViewTarget->changeFrame(robot, headFrameName);
399 int closestNodeIndex = graphLookupTable->getClosestNode(positionInSphereCoordinates);
401 float halfCameraOpeningAngle = 12.0 *
M_PI / 180.0;
402 float modifiedHalfCameraOpeningAngle = halfCameraOpeningAngle;
403 float distance = currentViewTarget->toEigen().norm();
412 const float distanceThreshold = 1500;
415 modifiedHalfCameraOpeningAngle = (
distance - 0.1f * distanceThreshold) / (0.9f * distanceThreshold) * halfCameraOpeningAngle;
416 modifiedHalfCameraOpeningAngle =
std::max(0.0f, modifiedHalfCameraOpeningAngle);
420 std::vector<bool> visitedNodes(saliencyEgosphereGraph->getNodes()->size(),
false);
421 addSaliencyRecursive(closestNodeIndex, visitedNodes, saliency, positionInSphereCoordinates, modifiedHalfCameraOpeningAngle);
428 for (std::size_t row = 0; centers.rows > 0 && row < static_cast<std::size_t>(centers.rows); row++)
430 for (std::size_t i = 0; i < 8; i++)
432 for (std::size_t j = 0; j < 8; j++)
434 index = 3 * (((int)centers.at<
float>(row, 1) * scaleFactor + i) * images[0]->width + ((
int)centers.at<
float>(row, 0) * scaleFactor + j));
435 result[2]->pixels[
index] = 255;
436 result[2]->pixels[
index + 1] = 255 * (row == maxCluster);
437 result[2]->pixels[
index + 2] = 255 * (row ==
static_cast<std::size_t
>(secondCluster));
447 provideResultImages(result);
449 SaliencyMapBasePtr primitiveSaliency =
new SaliencyMapBase();
450 primitiveSaliency->name =
"ValveAttention";
451 saliencyEgosphereGraph->graphToVec(primitiveSaliency->map);
452 viewSelection->updateSaliencyMap(primitiveSaliency);
458 void ValveAttention::addSaliencyRecursive(
const int currentNodeIndex, std::vector<bool>& visitedNodes,
const float saliency,
const TSphereCoord objectSphereCoord,
const float maxDistanceOnArc)
466 float newValue = ((
CIntensityNode*)saliencyEgosphereGraph->
getNodes()->at(currentNodeIndex))->getIntensity()
467 + (1.0f - 0.5f * normalizedDistance * normalizedDistance) * saliency;
471 ARMARX_INFO <<
"saliency is greater than 1.0: " << newValue;
472 newValue =
std::min(1.0f, newValue);
478 visitedNodes.at(currentNodeIndex) =
true;
483 for (
size_t i = 0; i < saliencyEgosphereGraph->
getNodeAdjacency(currentNodeIndex)->size(); i++)
485 neighbourIndex = saliencyEgosphereGraph->
getNodeAdjacency(currentNodeIndex)->at(i);
487 if (!visitedNodes.at(neighbourIndex))
491 addSaliencyRecursive(neighbourIndex, visitedNodes, saliency, objectSphereCoord, maxDistanceOnArc);
495 visitedNodes.at(neighbourIndex) =
true;