Skip to content

Commit

Permalink
IT-1313: enforce single frame row tracking export (#1411)
Browse files Browse the repository at this point in the history
Co-authored-by: Nosheen Adil <[email protected]>
  • Loading branch information
nosheen-adil and Nosheen Adil authored Aug 30, 2024
1 parent 5f4d6da commit 42a18c0
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 69 deletions.
9 changes: 9 additions & 0 deletions api/isxNVisionTracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ class ZoneEvent
/// @return The zone event type represented as a string
static std::string typeToStr(const Type type);

/// @brief Converts type to a full string representation
/// (not a single char embedded in frame metadata)
/// @param type The zone event type to convert to string
/// @return The zone event type represented as a string
static std::string typeToFullStr(const Type type);

/// @brief The trigger of the zone event (for closed-loop systems).
/// Maps to the SoftTrig 1-4 channels in the corresponding gpio file.
enum class Trigger
Expand Down Expand Up @@ -111,6 +117,9 @@ class ZoneEvent
/// @brief A map of zone event triggers to string representations in json metadata
const static std::map<Trigger, std::string> s_triggerToStrMap;

/// @brief A map of zone event triggers to string representations in json metadata
const static std::map<Type, std::string> s_typeToFullStrMap;

/// @brief The zone id for the zone event.
int64_t m_zoneId = -1;

Expand Down
154 changes: 86 additions & 68 deletions src/isxMovieExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,100 +457,118 @@ writeNVisionTrackingBoundingBoxToCsv(
{
const auto movie = movies[movieNumber];
const auto timingInfo = movie->getTimingInfo();

size_t localFrameNumber = 0;
while (localFrameNumber < timingInfo.getNumTimes())
for (size_t localFrameNumber = 0; localFrameNumber < timingInfo.getNumTimes(); localFrameNumber++)
{
csv << globalFrameNumber << "," << movieNumber << "," << localFrameNumber << ",";

if (!timingInfo.isIndexValid(localFrameNumber))
{
for (size_t i = 0; i < (numColumns - numFrameNumColumns - 1); i++)
{
csv << ",";
}
csv << std::endl;
globalFrameNumber++;
continue;
}

const auto tsc = movie->getFrameTimestamp(localFrameNumber);
if (timestampFormat == WriteTimeRelativeTo::FIRST_DATA_ITEM)
{
const auto timestamp = double(tsc - firstTsc) / 1e6;
csv << std::fixed << std::setprecision(6) << timestamp;
}
else if (timestampFormat == WriteTimeRelativeTo::UNIX_EPOCH)
{
const auto timestamp = epochStartTimestamp + (double(tsc - firstTsc) / 1e6);
csv << std::fixed << std::setprecision(6) << timestamp;
}
else
{
csv << tsc;
}
csv << ",";

const auto boundingBox = BoundingBox::fromMetadata(
movie->getFrameMetadata(localFrameNumber)
);
auto zoneEvents = boundingBox.getZoneEvents();
if (zoneEvents.empty())

if (!boundingBox.isValid())
{
// for no zone events, create an empty zone which will be detected
// in the for loop that follows
zoneEvents = {isx::ZoneEvent()};
// add one more column to cut for timestamp column
for (size_t i = 0; i < (numColumns - numFrameNumColumns - 1 - 1); i++)
{
csv << ",";
}
csv << std::endl;
globalFrameNumber++;
continue;
}

csv << boundingBox.getLeft() << ","
<< boundingBox.getTop() << ","
<< boundingBox.getRight() << ","
<< boundingBox.getBottom() << ",";

// for each frame, and each zone event that occurred in that frame,
// write a line in the csv output
for (const auto & zoneEvent : zoneEvents)
const auto center = boundingBox.getCenter();
csv << center.getX() << ","
<< center.getY() << ","
<< boundingBox.getConfidence() << ",";

// combine zone event info into a single cell of the csv
std::string zoneIdStr = "";
std::string zoneNameStr = "";
std::string zoneEventStr = "";
std::string zoneTriggerStr = "";
size_t numZones = 0;
for (const auto & zoneEvent : boundingBox.getZoneEvents())
{
csv << globalFrameNumber << "," << movieNumber << "," << localFrameNumber << ",";

if (!timingInfo.isIndexValid(localFrameNumber))
if (zoneEvent.getType() == ZoneEvent::Type::NONE && zoneEvent.getZoneId() == 0)
{
for (size_t i = 0; i < (numColumns - numFrameNumColumns - 1); i++)
{
csv << ",";
}
csv << std::endl;
globalFrameNumber++;
continue;
}

const auto tsc = movie->getFrameTimestamp(localFrameNumber);
if (timestampFormat == WriteTimeRelativeTo::FIRST_DATA_ITEM)
{
const auto timestamp = double(tsc - firstTsc) / 1e6;
csv << std::fixed << std::setprecision(6) << timestamp;
}
else if (timestampFormat == WriteTimeRelativeTo::UNIX_EPOCH)
if (!zoneIdStr.empty())
{
const auto timestamp = epochStartTimestamp + (double(tsc - firstTsc) / 1e6);
csv << std::fixed << std::setprecision(6) << timestamp;
zoneIdStr += ",";
}
else
zoneIdStr += std::to_string(zoneEvent.getZoneId());

if (!zoneNameStr.empty())
{
csv << tsc;
zoneNameStr += ",";
}
csv << ",";

const auto boundingBox = BoundingBox::fromMetadata(
movie->getFrameMetadata(localFrameNumber)
);
zoneNameStr += zoneEvent.getZoneName();

if (!boundingBox.isValid())
if (!zoneEventStr.empty())
{
// add one more column to cut for timestamp column
for (size_t i = 0; i < (numColumns - numFrameNumColumns - 1 - 1); i++)
{
csv << ",";
}
csv << std::endl;
globalFrameNumber++;
continue;
zoneEventStr += ",";
}
zoneEventStr += ZoneEvent::typeToFullStr(zoneEvent.getType());

csv << boundingBox.getLeft() << ","
<< boundingBox.getTop() << ","
<< boundingBox.getRight() << ","
<< boundingBox.getBottom() << ",";

const auto center = boundingBox.getCenter();
csv << center.getX() << ","
<< center.getY() << ","
<< boundingBox.getConfidence() << ",";

const auto zoneId = zoneEvent.getZoneId();
if (zoneId < 0)
if (!zoneTriggerStr.empty())
{
// invalid zone (which means no zone events for this frame)
csv << ",,,";
zoneTriggerStr += ",";
}
else
{
csv << zoneId << ","
<< zoneEvent.getZoneName() << ","
<< isx::ZoneEvent::typeToStr(zoneEvent.getType()) << ","
<< isx::ZoneEvent::triggerToStr(zoneEvent.getTrigger());
zoneTriggerStr += ZoneEvent::triggerToStr(zoneEvent.getTrigger());

}
numZones++;
}

csv << std::endl;
if (numZones > 1)
{
csv << "\"" << zoneIdStr << "\","
<< "\"" << zoneNameStr << "\","
<< "\"" << zoneEventStr << "\","
<< "\"" << zoneTriggerStr << "\"";
}
else
{
csv << zoneIdStr << "," << zoneNameStr
<< "," << zoneEventStr << "," << zoneTriggerStr;
}

localFrameNumber++;
csv << std::endl;
globalFrameNumber++;
}
}
Expand Down
14 changes: 14 additions & 0 deletions src/isxNVisionTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ const std::map<ZoneEvent::Type, std::string> ZoneEvent::s_typeToStrMap = {
{ZoneEvent::Type::EXIT, "x"}
};

const std::map<ZoneEvent::Type, std::string> ZoneEvent::s_typeToFullStrMap = {
{ZoneEvent::Type::NONE, ""},
{ZoneEvent::Type::ENTRY, "entry"},
{ZoneEvent::Type::OCCUPIED, "occupying"},
{ZoneEvent::Type::EXIT, "exit"}
};


const std::map<ZoneEvent::Trigger, std::string> ZoneEvent::s_triggerToStrMap = {
{ZoneEvent::Trigger::NONE, ""},
{ZoneEvent::Trigger::SOFT_TRIG_1, "softTrig-1"},
Expand Down Expand Up @@ -40,6 +48,12 @@ ZoneEvent::typeToStr(const ZoneEvent::Type type)
return s_typeToStrMap.at(type);
}

std::string
ZoneEvent::typeToFullStr(const ZoneEvent::Type type)
{
return s_typeToFullStrMap.at(type);
}

ZoneEvent::Trigger
ZoneEvent::strToTrigger(const std::string str)
{
Expand Down
2 changes: 1 addition & 1 deletion test/MovieExportTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ TEST_CASE("NVisionMovieTrackingDataExportTest", "[core]")
const std::string actualFirstLine(buf.get());
REQUIRE(actualFirstLine == expectedFirstLine);

const std::string expectedLastLine = "9,0,9,1720007659.987005,1201.097168,805.654907,1293.367554,928.300720,1247.232422,866.977783,21.289660,1720032796530,ZONE#3,o,softTrig-3";
const std::string expectedLastLine = "9,0,9,1720007659.987005,1201.097168,805.654907,1293.367554,928.300720,1247.232422,866.977783,21.289660,1720032796530,ZONE#3,occupying,softTrig-3";
#if ISX_OS_WIN32
strm.seekg(-int64_t(expectedLastLine.size() + 2), std::ios_base::end);
#else
Expand Down

0 comments on commit 42a18c0

Please sign in to comment.