28 #include <Base/Common/W32Compat.hh>
30 #include <Base/Debug/Error.hh>
31 #include "ImageBase.hh"
38 #define ROI_IDENTIFIER "MIP-ROI"
39 #define ROI_IDENTIFIER_LENGTH 7
68 os <<
"Unknown ROI type" << type;
77 os <<
"[" << pos.
x <<
", " << pos.
y <<
"]";
84 os <<
"ROI (" << roi.
Width_ <<
"x" << roi.
Height_ <<
") type: "
93 vector<Position>::const_iterator it;
99 for (
unsigned y = 0; y < roi.
Height_; y++)
105 BEXCEPTION(
"unknonw roi type "<<roi.
RoiType_);
123 RoiType_(
ROI_Corners), Width_(0), Height_(0), UpperLeftX_(0), UpperLeftY_(0),
124 LowerRightX_(0), LowerRightY_(0), Mask_(), Vector_(), RowStart_(),
132 RoiType_(
ROI_Corners), Width_(0), Height_(0), UpperLeftX_(0), UpperLeftY_(0),
133 LowerRightX_(0), LowerRightY_(0), Mask_(), Vector_(), RowStart_(),
182 if (
Mask_.size()!=roi.
Mask_.size())
return false;
183 for (
unsigned i=0; i<
Mask_.size(); i++){
190 for (
unsigned i=0; i<
Vector_.size(); i++){
199 for (
unsigned i=0; i<
Vector_.size(); i++){
206 BIASERR(
"ROI::operator==() unfinished code");
257 BEXCEPTION(
"Unknown ROI type "<<
RoiType_<<
" given");
275 BEXCEPTION(
"Unknown ROI type "<<
RoiType_<<
" given");
288 unsigned LowerRightX,
unsigned LowerRightY)
297 BIASWARN(
"UpperLeftX "<<UpperLeftX<<
" is <0");
300 else if( UpperLeftX >
Width_)
302 BIASWARN(
"UpperLeftX "<<UpperLeftX<<
" is out of image range "<<
Width_);
307 BIASWARN(
"UpperLeftY "<<UpperLeftY<<
" is <0");
312 BIASWARN(
"UpperLeftY "<<UpperLeftY<<
" is out of image range "<<
Height_);
315 if (LowerRightX < 0 )
317 BIASWARN(
"LowerRightX "<<LowerRightX<<
" is < 0");
320 else if( LowerRightX >
Width_ )
322 BIASWARN(
"LowerRightX "<<LowerRightX<<
" is out of image range "<<
Width_);
328 BIASWARN(
"LowerRightY "<<LowerRightY<<
" is <0");
331 else if (LowerRightY >
Height_ )
333 BIASWARN(
"LowerRightY "<<LowerRightY<<
" is out of image range "<<
Height_);
336 if (LowerRightX < UpperLeftX)
339 BIASWARN(
"WARNING: You swapped the x coordinates of the upper left:"<<UpperLeftX<<
" and the"
340 <<
" lower right "<<LowerRightX<<
" corner. ");
343 unsigned int temp = UpperLeftX;
344 UpperLeftX = LowerRightX;
348 if (LowerRightY < UpperLeftY)
350 BIASWARN(
"WARNING: You swapped the y coordinates of the upper left:"<<UpperLeftY<<
" and the"
351 <<
" lower right "<<LowerRightY<<
"corner.");
354 unsigned int temp = UpperLeftY;
355 UpperLeftY = LowerRightY;
386 unsigned char *dst = (
unsigned char *) im.
GetImageData();
387 for (
unsigned y = 0; y <
Height_; y++)
389 for (
unsigned x = 0; x <
Width_; x++)
391 dst[y * Width_ + x] = (
Mask(x, y)) ? (0) : (numeric_limits<
392 unsigned char>::max());
409 const unsigned char *ida =
411 for (
unsigned y = 0; y <
Height_; y++)
413 for (
unsigned x = 0; x <
Width_; x++)
415 SetMask(x, y, (ida[y * Width_ + x] == 0));
421 BIASERR(
"Wrong mask image given, single channel unsigned "
422 "character image expected!");
437 const std::vector<unsigned>& end)
442 BEXCEPTION(
"invalid argument vector size ("<<
Height_<<
"): "
443 <<start.size()<<
" "<<end.size());
445 for (
unsigned y = 0; y <
Height_; y++)
447 if (start[y] > end[y])
449 BEXCEPTION(
"invalid argument vector content: start>end "<<start[y]
454 BEXCEPTION(
"invalid argument vector content: end > width "<<end[y]
482 BEXCEPTION(
"Out of bounds of mask image ("<<x<<
", "<<y<<
")");
492 BEXCEPTION(
"Out of bounds of mask image ("<<x<<
", "<<y<<
")");
513 os.write(ROI_IDENTIFIER, ROI_IDENTIFIER_LENGTH);
514 os.write(reinterpret_cast<const char*> (&
Version_),
sizeof(
int));
516 os.write(reinterpret_cast<const char*> (&
Width_),
sizeof(
unsigned));
517 os.write(reinterpret_cast<const char*> (&
Height_),
sizeof(
unsigned));
520 BCDOUT(D_ROI_IO,
"wrote roi type: "<<
RoiType_<<endl);
525 os.write(reinterpret_cast<const char*> (&
UpperLeftX_),
sizeof(
unsigned));
526 os.write(reinterpret_cast<const char*> (&
UpperLeftY_),
sizeof(
unsigned));
527 os.write(reinterpret_cast<const char*> (&
LowerRightX_),
sizeof(
unsigned));
528 os.write(reinterpret_cast<const char*> (&
LowerRightY_),
sizeof(
unsigned));
532 unsigned length = (int)
Vector_.size();
533 os.write(reinterpret_cast<const char*> (&length),
sizeof(
unsigned));
534 vector<Position>::const_iterator it;
537 BCDOUT(D_ROI_IO,
"writing " << *it << endl);
538 os.write(reinterpret_cast<const char*> (&(it->x)),
sizeof(
unsigned));
539 os.write(reinterpret_cast<const char*> (&(it->y)),
sizeof(
unsigned));
545 for (
unsigned y = 0; y <
Height_; y++)
547 for (
unsigned x = 0; x <
Width_; x++)
550 tmp =
Mask_[y * Width_ + x];
551 os.write(reinterpret_cast<const char*> (&(tmp)),
sizeof(
bool));
556 for (
unsigned y = 0; y <
Height_; y++)
558 os.write(reinterpret_cast<const char*> (&(
RowStart_[y])),
560 os.write(reinterpret_cast<const char*> (&(
RowEnd_[y])),
565 BEXCEPTION(
"Unknown ROI type "<<
RoiType_<<
" given");
569 return (os.good()) ? 0 : -2;
577 char identifier[ROI_IDENTIFIER_LENGTH];
580 vector<Position>::iterator it;
583 is.read(identifier, ROI_IDENTIFIER_LENGTH);
584 if (strncmp(identifier, ROI_IDENTIFIER, ROI_IDENTIFIER_LENGTH) != 0)
586 BIASERR(
"invalid ROI identifier "<<identifier<<endl);
589 is.read(reinterpret_cast<char*> (&Version),
sizeof(
int));
596 is.read(reinterpret_cast<char*> (&
UpperLeftX_),
sizeof(
unsigned));
597 is.read(reinterpret_cast<char*> (&
UpperLeftY_),
sizeof(
unsigned));
598 is.read(reinterpret_cast<char*> (&
LowerRightX_),
sizeof(
unsigned));
599 is.read(reinterpret_cast<char*> (&
LowerRightY_),
sizeof(
unsigned));
602 is.read(reinterpret_cast<char*> (&w),
sizeof(
unsigned));
603 is.read(reinterpret_cast<char*> (&h),
sizeof(
unsigned));
606 is.read(reinterpret_cast<char*> (&length),
sizeof(
unsigned));
610 is.read(reinterpret_cast<char*> (&MaskValid),
sizeof(
bool));
611 is.read(reinterpret_cast<char*> (&VectorValid),
sizeof(
bool));
612 BCDOUT(D_ROI_IO,
"read MaskValid "<<boolalpha<<MaskValid
613 <<
" VectorValid "<<boolalpha<<VectorValid<<endl);
615 if (MaskValid && VectorValid)
617 BEXCEPTION(
"roi can no longer hold mask and vectors concurrently");
621 unsigned char *mask =
new unsigned char[w * h];
622 BCDOUT(D_ROI_IO,
"reading mask image of size "
625 *
sizeof(
unsigned char));
627 for (
unsigned y = 0; y <
Height_; y++)
629 for (
unsigned x = 0; x <
Width_; x++)
631 SetMask(x, y, (mask[y * Width_ + x] == 0));
636 else if (VectorValid)
640 BCDOUT(D_ROI_IO,
"reading vector of length "<<
Vector_.size()<<endl);
643 is.read(reinterpret_cast<char*> (&(it->x)),
sizeof(
unsigned));
644 is.read(reinterpret_cast<char*> (&(it->y)),
sizeof(
unsigned));
645 BCDOUT(D_ROI_IO,
"read "<<*it<<endl);
648 res = (is.good()) ? 0 : -3;
654 is.read(reinterpret_cast<char*> (&w),
sizeof(
unsigned));
655 is.read(reinterpret_cast<char*> (&h),
sizeof(
unsigned));
659 is.read(reinterpret_cast<char*> (&type),
sizeof(
enum ERoiType));
665 is.read(reinterpret_cast<char*> (&
UpperLeftX_),
sizeof(
unsigned));
666 is.read(reinterpret_cast<char*> (&
UpperLeftY_),
sizeof(
unsigned));
667 is.read(reinterpret_cast<char*> (&
LowerRightX_),
sizeof(
unsigned));
668 is.read(reinterpret_cast<char*> (&
LowerRightY_),
sizeof(
unsigned));
672 is.read(reinterpret_cast<char*> (&length),
sizeof(
unsigned));
674 BCDOUT(D_ROI_IO,
"reading vector of length "<<
Vector_.size()<<endl)
678 is.read(reinterpret_cast<char*> (&(it->x)),
sizeof(
unsigned));
679 is.read(reinterpret_cast<char*> (&(it->y)),
sizeof(
unsigned));
680 BCDOUT(D_ROI_IO,
"read "<<*it<<endl);
685 for (
unsigned y = 0; y <
Height_; y++)
687 for (
unsigned x = 0; x <
Width_; x++)
689 is.read(reinterpret_cast<char*> (&tmp),
sizeof(
bool));
695 for (
unsigned y = 0; y <
Height_; y++)
697 is.read(reinterpret_cast<char*> (&(
RowStart_[y])),
sizeof(
unsigned));
698 is.read(reinterpret_cast<char*> (&(
RowEnd_[y])),
sizeof(
unsigned));
702 BEXCEPTION(
"Unknown ROI type "<<
RoiType_<<
" given");
707 BIASERR(
"Unknown ROI version "<<Version<<
"!");
772 BIASERR(
"Source ROI for conversion has unknown type " <<
RoiType_ <<
"!");
775 BIASERR(
"Unknown target ROI type " << type <<
" for conversion given!");
782 BEXCEPTION(
"Unfinished ROI conversion from corners to mask!");
789 BEXCEPTION(
"Unfinished ROI conversion from corners to point vector!");
796 BEXCEPTION(
"Unfinished ROI conversion from corners to rows!");
803 BEXCEPTION(
"Invalid ROI conversion from mask to corners!");
812 register unsigned y = 0, x = 0;
813 vector<Position> vec;
817 for (x = 0; x <
Width_; x++)
830 BEXCEPTION(
"Invalid ROI conversion from mask to rows!");
850 vector<Position> vec;
852 vector<Position>::iterator it;
854 for (it = vec.begin(); it != vec.end(); it++)
857 if (!(it->y >= 0 && it->x >= 0 &&
860 BIASASSERT(it->y >= 0 && it->x >= 0 &&
871 BEXCEPTION(
"Invalid ROI conversion from point vector to rows!");
878 BEXCEPTION(
"Unfinished ROI conversion from rows to corners!");
885 BEXCEPTION(
"Unfinished ROI conversion from rows to mask!");
892 BEXCEPTION(
"Unfinished ROI conversion from rows to point vector!");
948 BEXCEPTION(
"empty ROI");
955 const int hws = half_mask_size;
967 bool found_start =
false;
970 for (i=-hws; i<=hws; i++){
989 bool found_end =
false;
992 for (i=-hws; i<=hws; i++){
1015 BIASERR(
"Erode() is not implemented yet for this ROI type!");
int Corners2Vector_()
Fills vector representation of ROI from corner representation.
int Corners2Mask_()
Fills mask representation of ROI from corner representation.
int Mask2Corners_()
Fills corner/bounding box representation of ROI from mask representation.
stores valid/nvalid positions in image
class for handling different region of interest (ROI) representations...
int SetCorners(unsigned UpperLeftX, unsigned UpperLeftY, unsigned LowerRightX, unsigned LowerRightY)
Sets a rectangular region of interest.
void Resize(unsigned width, unsigned height)
Resizes parent image.
void Release()
Deletes internal memory, sets mask and vector invalid.
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
bool SameSize(const ROI &roi) const
Returns true if both ROIs have the same size.
std::vector< bool > Mask_
internal data for ROI of type ROI_Mask the mask data: Mask_[y*Width_+x] corresponds to pixel at (x...
unsigned x
member variables
int Mask2Vector_()
Fills vector representation of ROI from mask representation.
int Vector2Rows_()
Fills rows representation of ROI from vector representation.
bool Mask(const unsigned &x, const unsigned &y) const
Direct access to the mask data, const version.
unsigned GetWidth() const
width capacity of roi (image width)
void UnsetROI()
Delete region of interest.
unsigned int GetWidth() const
int WriteBinary(std::ostream &os) const
binary output to stream
int Corners2Rows_()
Fills rows representation of ROI from corner representation.
void SetROIType(const enum ERoiType &type)
alloc and free of internal memory
enum ERoiType RoiType_
which method is used to store the ROI
int SetMaskImage(const ImageBase &im)
every pixel with value==0.0 is in the ROI, every pixel with value!=0.0 is not in the ROI ...
invalid not set image storage type
unsigned Width_
maximum dimension of roi data
const void * GetImageData() const
std::vector< Position > * GetVector()
returns a pointer to the vector representation of the ROI
int ReadBinary(std::istream &is)
binary input from stream
bool VectorValid() const
is the position vector valid?
int Rows2Vector_()
Fills vector representation of ROI from rows representation.
int Vector2Corners_()
Fills corner/bounding box representation of ROI from vector representation.
int Rows2Corners_()
Fills corner representation of ROI from rows representation.
bool operator==(const ROI &roi) const
comparison
bool IsInROI(const double &x, const double &y) const
ROI check if pixel position is inside the ROI.
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
void Erode(const ROI &src, const unsigned half_mask_size)
int Rows2Mask_()
Fills mask representation of ROI from rows representation.
unsigned int GetHeight() const
long int NewDebugLevel(const std::string &name)
creates a new debuglevel
std::ostream & operator<<(std::ostream &os, const Array2D< T > &arg)
unsigned UpperLeftX_
internal data for ROI of type ROI_Corners rectangular region of interest defined by upper left and lo...
ROI & operator=(const ROI &roi)
assignment operator
static const int Version_
version number of ROI class
std::vector< unsigned > RowEnd_
void Release(const bool reset_storage_type=false)
Free the allocated data structures Hands off: Do !!NOT!! change the default of reset_storage_type: Im...
bool MaskValid() const
is the position vector valid?
int ConvertROIType(const enum ERoiType &type)
Generic conversion function from current ROI representation to the given ROI representation.
void Init(unsigned int width, unsigned int height, unsigned int nChannels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
Initialize image size and channels.
enum EStorageType GetStorageType() const
(8bit) unsigned char image storage type
unsigned GetHeight() const
height capacity of roi (image height)
void SetMask(const unsigned &x, const unsigned &y, const bool val)
Direct access to the mask data.
void SetVector(std::vector< Position > &pos)
Sets MaskValid_=false and VectorValid_=true.
int Mask2Rows_()
Fills rows representation of ROI from mask representation.
This is the base class for images in BIAS.
int GetMaskImage(ImageBase &im) const
returns an image of StorageType unsigned char, where every pixel not in the ROI is set to UCHAR_MAX a...
std::vector< Position > Vector_
internal data for ROI of type ROI_Points Vector instance of ROI, always sorted from top left to botto...
void SetRows(const std::vector< unsigned > &start, const std::vector< unsigned > &end)
Horizontal start and end position per image row, the length of the vectors always corresponds to the ...
int Vector2Mask_()
Fills vector representation of ROI from mask representation.
std::vector< unsigned > RowStart_
internal data for ROI of type ROI_Rows the ROI is specified by a min and a max value for each row in ...