I am trying to convert a call to groupRectangles()
from python to c++, and have noticed the output from the python binding does not match the output to the c++ call.
Library version
I am running opencv on Ubuntu 16.04.
The c++ program is linked against opencv 2.4.9 (as reported by ldd).
The python module reports version 2.4.9.1
C++ code
I wrote the following program to take a a set of (x1, y1, x2, y2) inputs and pass them to groupRectangles()
with a group threshold of 3 and an epsilon of 0.02. For ease of comparison, the output is printed in python's list format.
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
// display in python format
std::ostream& operator<<(std::ostream& out, std::vector<cv::Rect>& rectangles)
{
out << '[';
for (auto i = 0u; i<rectangles.size(); ++i)
{
if (i)
out << ',';
out << '[' << rectangles[i].tl().x << ',' << rectangles[i].tl().y << ',' << rectangles[i].br().x << ',' << rectangles[i].br().y << ']';
}
return out << ']';
}
// inputs are x1,y1,x2,y2
constexpr const float inputs[][4] = {{547,432,701,639},{557,435,700,640},{560,438,695,641},{560,438,694,640},{88,443,336,663},{83,444,357,671},{83,444,373,676},{87,449,377,676},{87,454,380,677},{76,453,388,680},{72,447,394,683},{80,437,393,683},{101,430,392,678},{547,433,702,641},{555,433,701,645},{558,437,696,647},{556,440,696,644},{84,443,357,664},{73,448,369,665},{74,449,375,664},{81,451,373,664},{85,454,375,666},{81,454,385,672},{74,452,392,676},{77,445,396,679},{91,433,392,680},{547,430,705,644},{553,429,704,649},{555,434,697,649},{552,438,695,649},{85,445,365,661},{69,451,376,662},{69,452,379,663},{76,453,374,663},{80,452,377,666},{79,451,382,671},{74,449,388,673},{77,445,393,673},{90,434,389,674},{546,429,706,643},{553,428,703,647},{554,432,695,649},{553,435,693,654},{81,445,370,663},{68,454,383,664},{67,455,388,664},{72,454,384,667},{77,452,382,669},{71,448,386,671},{66,443,388,672},{73,438,389,671},{92,429,388,673},{545,429,706,642},{553,429,703,643},{553,432,695,647},{553,432,696,658},{79,450,367,664},{72,459,379,663},{71,459,387,665},{75,458,388,667},{75,455,390,666},{65,448,389,668},{63,441,387,669},{73,433,384,672},{100,425,388,675},{549,429,707,648},{550,429,701,652},{554,434,703,662},{79,462,356,665},{73,462,374,665},{74,461,383,666},{73,460,387,667},{69,457,391,664},{60,447,390,668},{63,435,385,673},{81,430,384,676},{116,433,390,677}};
int main()
{
std::vector<cv::Rect> candidates;
std::transform(std::begin(inputs), std::end(inputs), std::back_inserter(candidates),
[](const float coord[4]) {
return cv::Rect(cv::Point((int)coord[0], (int)coord[1]), cv::Point((int)coord[2], (int)coord[3]));
});
std::cout << "input:\n" << candidates << '\n';
std::vector<int> weights(candidates.size());
cv::groupRectangles(candidates, weights, 3, 0.02);
std::cout << "output:\n" << candidates << '\n';
return EXIT_SUCCESS;
}
Test Execution
When executing the c++ program, I get the following output:
input:
[[547,432,701,639],[557,435,700,640],[560,438,695,641],[560,438,694,640],[88,443,336,663],[83,444,357,671],[83,444,373,676],[87,449,377,676],[87,454,380,677],[76,453,388,680],[72,447,394,683],[80,437,393,683],[101,430,392,678],[547,433,702,641],[555,433,701,645],[558,437,696,647],[556,440,696,644],[84,443,357,664],[73,448,369,665],[74,449,375,664],[81,451,373,664],[85,454,375,666],[81,454,385,672],[74,452,392,676],[77,445,396,679],[91,433,392,680],[547,430,705,644],[553,429,704,649],[555,434,697,649],[552,438,695,649],[85,445,365,661],[69,451,376,662],[69,452,379,663],[76,453,374,663],[80,452,377,666],[79,451,382,671],[74,449,388,673],[77,445,393,673],[90,434,389,674],[546,429,706,643],[553,428,703,647],[554,432,695,649],[553,435,693,654],[81,445,370,663],[68,454,383,664],[67,455,388,664],[72,454,384,667],[77,452,382,669],[71,448,386,671],[66,443,388,672],[73,438,389,671],[92,429,388,673],[545,429,706,642],[553,429,703,643],[553,432,695,647],[553,432,696,658],[79,450,367,664],[72,459,379,663],[71,459,387,665],[75,458,388,667],[75,455,390,666],[65,448,389,668],[63,441,387,669],[73,433,384,672],[100,425,388,675],[549,429,707,648],[550,429,701,652],[554,434,703,662],[79,462,356,665],[73,462,374,665],[74,461,383,666],[73,460,387,667],[69,457,391,664],[60,447,390,668],[63,435,385,673],[81,430,384,676],[116,433,390,677]]
output:
[[546,431,704,642],[70,447,389,672],[555,435,696,647],[74,455,381,666]]
In python, I cut-and-paste the c++ input as input to groupRectangles()
, but get completely different results:
cv2.groupRectangles([[547,432,701,639],[557,435,700,640],[560,438,695,641],[560,438,694,640],[88,443,336,663],[83,444,357,671],[83,444,373,676],[87,449,377,676],[87,454,380,677],[76,453,388,680],[72,447,394,683],[80,437,393,683],[101,430,392,678],[547,433,702,641],[555,433,701,645],[558,437,696,647],[556,440,696,644],[84,443,357,664],[73,448,369,665],[74,449,375,664],[81,451,373,664],[85,454,375,666],[81,454,385,672],[74,452,392,676],[77,445,396,679],[91,433,392,680],[547,430,705,644],[553,429,704,649],[555,434,697,649],[552,438,695,649],[85,445,365,661],[69,451,376,662],[69,452,379,663],[76,453,374,663],[80,452,377,666],[79,451,382,671],[74,449,388,673],[77,445,393,673],[90,434,389,674],[546,429,706,643],[553,428,703,647],[554,432,695,649],[553,435,693,654],[81,445,370,663],[68,454,383,664],[67,455,388,664],[72,454,384,667],[77,452,382,669],[71,448,386,671],[66,443,388,672],[73,438,389,671],[92,429,388,673],[545,429,706,642],[553,429,703,643],[553,432,695,647],[553,432,696,658],[79,450,367,664],[72,459,379,663],[71,459,387,665],[75,458,388,667],[75,455,390,666],[65,448,389,668],[63,441,387,669],[73,433,384,672],[100,425,388,675],[549,429,707,648],[550,429,701,652],[554,434,703,662],[79,462,356,665],[73,462,374,665],[74,461,383,666],[73,460,387,667],[69,457,391,664],[60,447,390,668],[63,435,385,673],[81,430,384,676],[116,433,390,677]], 3, 0.02)
(array([[553, 433, 700, 647],
[ 75, 449, 382, 669],
[ 95, 430, 390, 676]], dtype=int32), array([[23],
[46],
[ 5]], dtype=int32))
Is this an issue with my conversion to cv::Rect
, non-determinism in groupRectangles()
or something else?