#ifndef __LSGRM_SEGMENTER_H #define __LSGRM_SEGMENTER_H // Check windows #if _WIN32 || _WIN64 #if _WIN64 #define ENVIRONMENT64 #else #define ENVIRONMENT32 #endif #endif // Check GCC #if __GNUC__ #if __x86_64__ || __ppc64__ #define ENVIRONMENT64 #else #define ENVIRONMENT32 #endif #endif #include "macro-generator.h" #include "grmSegmenter.h" namespace lsgrm { template class Segmenter : public TSegmenterType { public: /* Some convenient typedefs */ typedef typename TSegmenterType::ImageType ImageType; typedef typename TSegmenterType::NodeType NodeType; typedef typename TSegmenterType::ParamType ParamType; typedef grm::Graph GraphType; typedef typename GraphType::EdgeType EdgeType; typedef typename GraphType::EdgeListType EdgeListType; typedef typename grm::GraphOperations GraphOperatorType; typedef typename GraphOperatorType::NodePointerType NodePointerType; typedef grm::GraphToOtbImage IOType; typedef typename IOType::LabelImageType LabelImageType; ~Segmenter(){}; /* * Given 1 smart node pointer (boost::shared_ptr), this * method writes the node specific attributes into the node stream. * * @params * NodePointerType n : Smart pointer of node * */ virtual void WriteSpecificAttributes(NodePointerType node, FILE * nodeStream) = 0; /* * Given 1 smart node pointer (boost::shared_ptr), this * method read the node specific attributes from the node stream. * * @params * NodePointerType n : Smart pointer of node * FILE * nodeStream : Node stream * */ virtual void ReadSpecificAttributes(NodePointerType node, FILE * nodeStream) = 0; /* * Given 1 smart node pointer (boost::shared_ptr), this * method writes the node into a stream. * * @params * NodePointerType n : Smart pointer of node * FILE * nodeStream : Node stream * */ void WriteNode(NodePointerType node, FILE * nodeStream) { fwrite(&(node->m_Id), sizeof(node->m_Id), 1, nodeStream); fwrite(&(node->m_Perimeter), sizeof(node->m_Perimeter), 1, nodeStream); fwrite(&(node->m_Area), sizeof(node->m_Area), 1, nodeStream); fwrite(&(node->m_Bbox.m_UX), sizeof(node->m_Bbox.m_UX), 1, nodeStream); fwrite(&(node->m_Bbox.m_UY), sizeof(node->m_Bbox.m_UY), 1, nodeStream); fwrite(&(node->m_Bbox.m_W), sizeof(node->m_Bbox.m_W), 1, nodeStream); fwrite(&(node->m_Bbox.m_H), sizeof(node->m_Bbox.m_H), 1, nodeStream); this->WriteSpecificAttributes(node, nodeStream); std::size_t contourSize = node->m_Contour.size(); fwrite(&(contourSize), sizeof(contourSize), 1, nodeStream); std::vector moves; moves.reserve(contourSize); for(unsigned int b = 0; b < contourSize; b++) { moves[b] = node->m_Contour[b]; } fwrite(&moves.front(), sizeof(short), contourSize, nodeStream); } /* * This method reads a graph from a stream. * * @params * FILE * nodeStream : Node stream * */ void ReadGraph(FILE * nodeStream, FILE * edgeStream) { std::unordered_map nodeMap; // Read the size of the graph { std::size_t graphSize; fread(&graphSize, sizeof(graphSize), 1, nodeStream); this->m_Graph.m_Nodes.reserve(graphSize); // Creation of the nodes for(std::size_t i = 0; i < graphSize; i++) { NodePointerType node(new NodeType()); node->m_Valid = true; node->m_Expired = false; node->m_IsMerged = true; // force to compute costs for the first iteration fread(&(node->m_Id), sizeof(node->m_Id), 1, nodeStream); fread(&(node->m_Perimeter), sizeof(node->m_Perimeter), 1, nodeStream); fread(&(node->m_Area), sizeof(node->m_Area), 1, nodeStream); fread(&(node->m_Bbox.m_UX), sizeof(node->m_Bbox.m_UX), 1, nodeStream); fread(&(node->m_Bbox.m_UY), sizeof(node->m_Bbox.m_UY), 1, nodeStream); fread(&(node->m_Bbox.m_W), sizeof(node->m_Bbox.m_W), 1, nodeStream); fread(&(node->m_Bbox.m_H), sizeof(node->m_Bbox.m_H), 1, nodeStream); this->ReadSpecificAttributes(node, nodeStream); { std::size_t contourSize; fread(&(contourSize), sizeof(contourSize), 1, nodeStream); std::vector moves; moves.reserve(contourSize); fread(&moves.front(), sizeof(short), contourSize, nodeStream); for(unsigned int b = 0; b < contourSize; b++) { node->m_Contour.push_back(moves[b]); } } nodeMap[node->m_Id] = node; this->m_Graph.m_Nodes.push_back(node); } } for(auto& node: this->m_Graph.m_Nodes) { std::size_t nodeId; fread(&(nodeId), sizeof(nodeId), 1, edgeStream); assert(nodeId == node->m_Id); std::size_t edgeSize; fread(&(edgeSize), sizeof(edgeSize), 1, edgeStream); node->m_Edges.reserve(edgeSize); for(unsigned int b = 0; b < edgeSize; b++) { std::size_t targetId; unsigned int boundary; fread(&(targetId), sizeof(targetId), 1, edgeStream); fread(&(boundary), sizeof(boundary), 1, edgeStream); node->m_Edges.push_back(EdgeType(nodeMap[targetId], 0, boundary)); } } } /* * This method writes the edge into a stream. * * @params * EdgePointerType edg : Smart pointer of edge * */ void WriteEdge(typename NodeType::CRPTNeighborType edg, FILE * edgeStream) { fwrite(&(edg.GetRegion()->m_Id), sizeof(edg.GetRegion()->m_Id), 1, edgeStream); fwrite(&(edg.m_Boundary), sizeof(edg.m_Boundary), 1, edgeStream); } /* * Returns the memory (in bytes) occupied by the specific attributes of the node */ virtual long long unsigned int GetSpecificAttributesMemory(NodePointerType &node) = 0; /* * Returns the memory (in bytes) occupied by the entire graph */ long long unsigned int GetGraphMemory() { long long unsigned int memory = 0; // sizeof(graph)... even if not significant memory += sizeof(GraphType); for(auto& node : this->m_Graph.m_Nodes) { // size of the contour (boost::dynamic_bitset) memory += sizeof(lp::Contour); #ifdef ENVIRONMENT64 memory += 8 * ((node->m_Contour.size() + 63) / 64); #endif #ifdef ENVIRONMENT32 memory += 8 * ((node->m_Contour.size() + 31) / 32); #endif // size of specific attributes memory += this->GetSpecificAttributesMemory(node); // size of the node pointer memory += sizeof(NodePointerType); // size of the node (actually, size of the base node) memory += sizeof(NodeType); // size of the edges memory += node->m_Edges.capacity() * sizeof(EdgeType); memory += sizeof(EdgeListType); } return memory; } /* Return the label image */ inline typename LabelImageType::Pointer GetLabeledClusteredOutput() { IOType io; auto labelImg = io.GetLabelImage(this->m_Graph, this->m_ImageWidth, this->m_ImageHeight); return labelImg; } }; } // end of namespace lsgrm #endif