123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- /*
- * NICE-Core - efficient algebra and computer vision methods
- * - libimage - An image/template for new NICE libraries
- * See file License for license information.
- */
- /*****************************************************************************/
- /*! \file Histogram.cpp
- \brief Histogram class definitions
- */
- #include <core/image/Histogram.h>
- namespace NICE {
- Histogram::Histogram() {
- _channels = 1;
- _min = 0;
- _max = 0;
- _nobins = 0;
- _diff = 0;
- _data = NULL;
- }
- Histogram::Histogram(const Ipp32s& bins) {
- _channels = 1;
- _min = 0;
- _max = 256;
- _nobins = bins;
- _diff = 256;
- _data = new VectorT<value_type>(_nobins,0);
- }
- Histogram::Histogram(const Ipp32s& min, const Ipp32s& max, const Ipp32s& bins) {
- _channels = 1;
- _min = min;
- _max = max;
- _nobins = (bins<0)?_max-_min:bins;
- _diff = _max-_min;
- _data = new VectorT<value_type>(_nobins,0);
- }
- Histogram::Histogram(const Image& src, const Ipp32s& min, const Ipp32s& max, const Ipp32s& bins) {
- _channels = 1;
- _min = min;
- _max = max;
- _nobins = (bins<0)?_max-_min:bins;
- _diff = _max-_min;
- _data = new VectorT<value_type>(_nobins,0);
- #ifdef NICE_USELIB_IPP
- Ipp32u noLevels = _nobins+1;
- Ipp32s pLevels[noLevels];
- IppStatus ret = ippiHistogramEven_C1R(src.getPixelPointer(), src.getStepsize(),
- makeROIFullImage(src),
- (Ipp32s*)_data->getDataPointer(),
- pLevels, noLevels, min, max);
- if(ret!=ippStsNoErr)
- fthrow(ImageException, ippGetStatusString(ret));
- #else // NICE_USELIB_IPP
- const Ipp8u* pSrc;
- const Ipp8u* pSrcStart = src.getPixelPointer();
- if(_min==0&&_max==256)
- for(int y=0; y<src.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<src.width(); ++x,++pSrc)
- (*_data)[((*pSrc-_min)*_nobins)/_diff]++;
- pSrcStart += src.getStepsize();
- }
- else
- for(int y=0; y<src.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<src.width(); ++x,++pSrc)
- if(isWithin(*pSrc))
- (*_data)[((*pSrc-_min)*_nobins)/_diff]++;
- pSrcStart += src.getStepsize();
- }
- #endif // NICE_USELIB_IPP
- }
- Histogram::Histogram(const Image& src, const Ipp32s& min, const Ipp32s& max,
- const Rect& rect, const Ipp32s& bins) {
- Rect tgtRect = clipRect(src, rect);
- const Image tgtImg = src.subImage(tgtRect);
- _channels = 1;
- _min = min;
- _max = max;
- _nobins = (bins<0)?_max-_min:bins;
- _diff = _max-_min;
- _data = new VectorT<value_type>(_nobins,0);
- #ifdef NICE_USELIB_IPP
- Ipp32u noLevels = _nobins+1;
- Ipp32s pLevels[noLevels];
- IppStatus ret = ippiHistogramEven_C1R(tgtImg.getPixelPointer(),
- tgtImg.getStepsize(),
- makeROIFullImage(tgtImg),
- _data->getDataPointer(),
- pLevels, noLevels, min, max);
- if(ret!=ippStsNoErr)
- fthrow(ImageException, ippGetStatusString(ret));
- #else // NICE_USELIB_IPP
- const Ipp8u* pSrc;
- const Ipp8u* pSrcStart = tgtImg.getPixelPointer();
- if(_min==0&&_max==256)
- for(int y=0; y<tgtImg.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<tgtImg.width(); ++x,++pSrc)
- (*_data)[((*pSrc-_min)*_nobins)/_diff]++;
- pSrcStart += src.getStepsize();
- }
- else
- for(int y=0; y<tgtImg.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<tgtImg.width(); ++x,++pSrc)
- if(isWithin(*pSrc))
- (*_data)[((*pSrc-_min)*_nobins)/_diff]++;
- pSrcStart += src.getStepsize();
- }
- #endif // NICE_USELIB_IPP
- }
- Histogram::Histogram(const ColorImage& src, const Ipp32s& min, const Ipp32s& max, const Ipp32s& bins) {
- _channels = 3;
- _min = min;
- _max = max;
- _nobins = (bins<0)?_max-_min:bins;
- _diff = _max-_min;
- _data = new VectorT<value_type>(3*_nobins,0);
- #ifdef NICE_USELIB_IPP
- Ipp32u noLevels = _nobins+1;
- Ipp32s *pLevels[_channels];
- int nLevels[_channels];
- Ipp32s tLevels[3*noLevels];
- Ipp32s *pHist[_channels], pmin[_channels], pmax[_channels];
- for(int i=0;i<3;i++) {
- pHist[i] = (Ipp32s*)(_data->getDataPointer() + i*_nobins);
- pLevels[i] = &tLevels[i*noLevels];
- nLevels[i] = noLevels;
- pmin[i] = _min;
- pmax[i] = _max;
- }
- IppStatus ret = ippiHistogramEven_C3R(src.getPixelPointer(), src.getStepsize(),
- makeROIFullImage(src), pHist,
- pLevels, nLevels, pmin, pmax);
- if(ret!=ippStsNoErr)
- fthrow(ImageException, ippGetStatusString(ret));
- #else // NICE_USELIB_IPP
- const Ipp8u* pSrc;
- const Ipp8u* pSrcStart = src.getPixelPointer();
- Ipp32u index;
- if(_min==0 && _max==256)
- for(int y=0; y<src.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<src.width(); ++x)
- for(int i=0; i<3; ++i,++pSrc) {
- index = ((*pSrc-_min)*_nobins)/_diff;
- (*_data)[index + i*_nobins]++;
- }
- pSrcStart += src.getStepsize();
- }
- else
- for(int y=0; y<src.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<src.width(); ++x)
- for(int i=0; i<3; ++i,++pSrc)
- if(isWithin(*pSrc)) {
- index = ((*pSrc-_min)*_nobins)/_diff;
- (*_data)[index + i*_nobins]++;
- }
- pSrcStart += src.getStepsize();
- }
- #endif // NICE_USELIB_IPP
- }
- Histogram::Histogram(const ColorImage& src, const Ipp32s& min, const Ipp32s& max,
- const Ipp32s& bins, const bool noLum) {
- _min = min;
- _max = max;
- _nobins = (bins<0)?_max-_min:bins;
- init_b();
- _diff = _max-_min;
- _channels = (noLum==false)?3:2;
- _data = new VectorT<value_type>( (_channels==3)?(_b[0]+_b[1]+_b[2]):(_b[1]+_b[2]), 0 );
- const Ipp8u* pSrc;
- const Ipp8u* pSrcStart = src.getPixelPointer();
- // noLum = false, include lum channel into calculation
- if(!noLum) {
- if(_min==0 && _max==256)
- for(int y=0; y<src.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<src.width(); ++x,pSrc+=3)
- (*_data)[ ((*pSrc-_min)*_b[0] + (*(pSrc+1)-_min)*_b[1] + (*(pSrc+2)-_min)*_b[2])/_diff ]++;
- pSrcStart += src.getStepsize();
- }
- else
- for(int y=0; y<src.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<src.width(); ++x,pSrc+=3)
- if(isWithin(*pSrc) && isWithin(*(pSrc+1)) && isWithin(*(pSrc+2)) )
- (*_data)[ ((*pSrc-_min)*_b[0] + (*(pSrc+1)-_min)*_b[1] + (*(pSrc+2)-_min)*_b[2])/_diff ]++;
- pSrcStart += src.getStepsize();
- }
- }
- // first channel is ignored
- else {
- if(_min==0 && _max==256)
- for(int y=0; y<src.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<src.width(); ++x,pSrc+=3)
- (*_data)[ ((*(pSrc+1)-_min)*_b[1]+(*(pSrc+2)-_min)*_b[2])/_diff ]++;
- pSrcStart += src.getStepsize();
- }
- else
- for(int y=0; y<src.height(); ++y) {
- pSrc = pSrcStart;
- for(int x=0; x<src.width(); ++x,pSrc+=3)
- if( isWithin(*(pSrc+1)) && isWithin(*(pSrc+2)) )
- (*_data)[ ((*(pSrc+1)-_min)*_b[1]+(*(pSrc+2)-_min)*_b[2])/_diff ]++;
- pSrcStart += src.getStepsize();
- }
- }
- }
- Ipp32u Histogram::reproject(const Ipp8u& c1, const Ipp8u& c2, const Ipp8u& c3) {
- if(channels()==1 || (size()>0 && size()==3*bins()))
- fthrow(ImageException,"No combined histogram is used.");
- if(_channels==2)
- return ((c2-_min)*_b[1]+(c3-_min)*_b[2])/_diff;
- else
- return ((c1-_min)*_b[0]+(c2-_min)*_b[1]+(c3-_min)*_b[2])/_diff;
- }
- Histogram::value_type Histogram::sum() const{
- return _data->Sum();
- }
- //
- FloatVector* Histogram::normalized() {
- FloatVector* result = new FloatVector(size());
- Ipp32f sum = static_cast<Ipp32f>(this->sum());
- #ifdef NICE_USELIB_IPP
- IppStatus ret;
- ret = ippsConvert_32s32f(getDataPointer(),
- result->getDataPointer(),
- size());
- if(ret!=ippStsNoErr)
- fthrow(ImageException, ippGetStatusString(ret));
- ret = ippsNormalize_32f(result->getDataPointer(),
- result->getDataPointer(),
- result->size(),
- 0.0, sum);
- if(ret!=ippStsNoErr)
- fthrow(ImageException, ippGetStatusString(ret));
- #else // NICE_USELIB_IPP
-
- FloatVector::iterator pDst = result->begin();
- for(iterator i=begin(); i!=end(); ++i,++pDst)
- *pDst = *i/sum;
- #endif
- return result;
- }
- IntVector* Histogram::cumulative() {
- IntVector* result = new IntVector(size());
- IntVector::iterator pDst = result->begin();
- *pDst++ = *(_data->begin());
- for(VectorT<value_type>::iterator i=begin()+1; i!=end(); ++i,++pDst)
- *pDst = *i+*(pDst-1);
- return result;
- }
- //
- Ipp32u Histogram::minIndex() const {
- return _data->MinIndex();
- }
- Ipp32u Histogram::maxIndex() const {
- return _data->MaxIndex();
- }
- // // // // // Input / Output // // // // //
- bool Histogram::read(const std::string &filename) {
- std::ifstream ifs(filename.c_str());
- if(!ifs)
- return false;
- int tsize;
- ifs >> tsize >> _channels >> _nobins >> _min >> _max;
- init_b();
- _diff = _max-_min;
- _data = new VectorT<value_type>(tsize);
- for(iterator i=begin(); i!=end(); ++i)
- ifs >> *i;
- ifs.close();
- return true;
- }
- bool Histogram::write(const std::string &filename) {
- std::ofstream ofs(filename.c_str());
- if(!ofs)
- return false;
- ofs << size() << "\n" << _channels << "\n" << _nobins << "\n" << _min << "\n" << _max << "\n";
- for(iterator i=begin(); i!=end(); ++i)
- ofs << *i << "\n";
- ofs.close();
- return true;
- }
- } // namespace NICE
|