void addScale( const AContainer& aligner, Point<double> scale ){ vector<ModifiedPlane> scales; scales.reserve( aligner.maskCount() ); for( unsigned i=0; i<aligner.maskCount(); i++ ){ auto& mask = aligner.mask( i ); scales.emplace_back( getScaled( mask, (mask.getSize() * scale).round() ) ); } items.emplace_back( scales ); }
//最后一步真正的释放对象 //释放自己,也释放关注自己的对象 void AWinControlBase::_lastRelease() { AContainer* pcParent = dynamic_cast<AContainer*>(GetParent()); if( pcParent ) pcParent->GetUICore()->RemoveWatcher(this); m_aWatchDelete.Clear(); Release(); }
static void setLimit( QCustomPlot& plot, const AContainer& images, Point<bool> moves ){ auto min_point = images.minPoint(); auto max_point = images.maxPoint(); plot.xAxis->setRange( moves.x ? min_point.x : 0, moves.x ? max_point.x : images.count() ); plot.yAxis->setRange( moves.y ? min_point.y : 0, moves.y ? max_point.y : images.count() ); plot.yAxis->setLabel( moves.y ? QObject::tr("Y") : QObject::tr("Id") ); plot.xAxis->setLabel( moves.y ? QObject::tr("X") : QObject::tr("Id") ); }
void display( ostream & out, const AContainer & C ) { out << "C = "; for ( typename AContainer::const_iterator it = C.begin(), it_end = C.end(); it != it_end; ++it ) { out << " (" << (*it).first << "," << (*it).second << ")"; } out << std::endl; }
ImageEx EstimatorRender::render(const AContainer &group, AProcessWatcher *watcher) const { auto planes_amount = group.image(0).size(); auto min_point = group.minPoint(); ProgressWrapper( watcher ).setTotal( planes_amount * iterations * group.count() ); auto est = AverageRender().render( group ); //Starting estimate est.scaleFactor( upscale_factor ); auto beta = color::WHITE * this->beta / group.count(); for( unsigned c=0; c<planes_amount; ++c ){ for( int i=0; i<iterations; i++ ){ if( ProgressWrapper(watcher).shouldCancel() ) return {}; auto output_copy = est[c]; //Improve estimate for( unsigned j=0; j<group.count(); j++, ProgressWrapper( watcher ).add() ) sign( output_copy, degrade( est[c], {group, j, c} ), group.image(j)[c], group.pos(j)-min_point , beta, channelScale(group, j, c)*upscale_factor ); //Regularization if( lambda > 0.0 ) regularize( est[c], output_copy, reg_size, alpha, beta, lambda ); else est[c] = output_copy; } //DEBUG: See how close our model gets to the input data for( unsigned j=0; j<group.count(); j++ ){ save( degrade( est[c], {group, j, c} ), "deg" + QString::number(c) + "-" + QString::number(j) ); save( group.image(j)[c], "low" + QString::number(c) + "-" + QString::number(j) ); } } return est; }
virtual void align( AContainer& container, AProcessWatcher* ) const override{ //Validate input auto max_frames = amount * repeats; if( amount < 1 || repeats < 1 ) throw std::runtime_error( "Invalid arguments, no frames would be generated" ); if( max_frames < offset ) throw std::runtime_error( "Offset is bigger than frames per cycle" ); //Calculate offsets for( unsigned i=0; i<container.count(); i++ ) container.setFrame( i, ((i + max_frames - offset)/repeats) % amount ); //Adding max_frames to be sure it is positive before MOD }
static Point<bool> imagesMoves( const AContainer& container ){ if( container.count() == 0 ) return { false, false }; Point<bool> moves{ false, false }; auto base = container.pos( 0 ); for( unsigned i=1; i<container.count(); ++i ){ auto current = container.pos( i ); moves.x = moves.x || (base.x != current.x); moves.y = moves.y || (base.y != current.y); } return moves; }
ImageEx PlaneRender::render( const AContainer& aligner, AProcessWatcher* watcher ) const{ unsigned planes_amount = aligner.image(0).size(); planes_amount = min( planes_amount, max_planes ); Progress progress( "PlaneRender", planes_amount, watcher ); //Render all planes auto color_space = aligner.image(0).getColorSpace(); ImageEx img( (planes_amount==1) ? color_space.changed( Transform::GRAY ) : color_space ); for( unsigned c=0; c<planes_amount; ++c ){ if( progress.shouldCancel() ) return {}; img.addPlane( renderPlane( aligner, c, progress.makeSubtask() ) ); } return img; }
void LinearAligner::align( AContainer& container, AProcessWatcher* watcher ) const { LinearFunc hor, ver;//, both; for( unsigned i=0; i<container.count(); i++ ){ hor.add( i, container.pos(i).x ); ver.add( i, container.pos(i).y ); //both.add( pos(i).x, pos(i).y ); } for( unsigned i=0; i<container.count(); i++ ){ switch( method ){ case AlignMethod::BOTH: container.setPos( i, { hor(i), ver(i) } ); break; case AlignMethod::VER: container.setPos( i, { 0, ver(i) } ); break; case AlignMethod::HOR: container.setPos( i, { hor(i), 0 } ); break; }; } }
void ARadioButton::SetChecked(bool v) { m_bChecked = v; if( v ) { AContainer* pContainer = dynamic_cast<AContainer *>(GetParent()); for(int i=0;i<pContainer->GetChildControls()->GetCount();i++) { AControl* pControl = (AControl *)(pContainer->GetChildControls()->operator [](i)); ARadioButton* pr = dynamic_cast<ARadioButton *>(pControl); if( pr == NULL || pr == this || pr->GetGroup() != (int)m_iGroup ) continue; pr->SetChecked(false); } } m_pUICore->Refresh(GetAbsPosition()); }
bool AScrollBar::IsContainerScrollBar() { bool bIsContainerScrollBar = false; AContainer* pContainer = dynamic_cast<AContainer*>(GetParent()); if( pContainer != NULL ) { if( m_Kind == sbVert ) { if( pContainer->GetVScrollBar() == this ) bIsContainerScrollBar = true; } else { if( pContainer->GetHScrollBar() == this ) bIsContainerScrollBar = true; } } return bIsContainerScrollBar; }
ImageEx JpegConstrainerRender::render(const AContainer &group, AProcessWatcher *watcher) const { //Get the one image we want to constrain if( group.count() != 1 ) throw std::runtime_error( "Can only be used on one image" ); auto img = group.image(0); //TODO: Check color types Progress progress( "JpegConstrainerRender", img.size(), watcher ); progress.loopAll( [&]( int c ){ //Constrain it to the Coeff unsigned change=0; img[c] = degrader.planes[c].degradeFromJpegPlane( img[c], jpeg.planes[c], change ); } ); return img; }
ImageEx DiffRender::render( const AContainer& aligner, unsigned max_count, AProcessWatcher* watcher ) const{ if( max_count > aligner.count() ) max_count = aligner.count(); //Normal render ImageEx avg = SimpleRender( SimpleRender::FOR_MERGING ).render( aligner, max_count ); //Find the smallest shared size QSize size = aligner.size().size(); //No image is larger than the final result for( unsigned i=0; i<max_count; i++ ){ size.setWidth( min( (unsigned)size.width(), aligner.image(i).get_width() ) ); size.setHeight( min( (unsigned)size.height(), aligner.image(i).get_height() ) ); } //Create final output image based on the smallest size ImageEx img( ImageEx::GRAY ); img.create( size.width(), size.height() ); Plane& output = img[0]; if( watcher ) watcher->setTotal( 1000 ); //Iterate over each pixel in the output image for( unsigned iy=0; iy<output.get_height(); iy++ ){ if( watcher ) watcher->setCurrent( iy * 1000 / output.get_height() ); color_type* out = output.scan_line( iy ); for( unsigned ix=0; ix<output.get_width(); ix++ ){ //Set the pixel to the static difference of all the images until max_count StaticDiff diff( aligner, avg, ix, iy ); for( unsigned j=0; j<max_count; j++ ) diff.add_image( j ); out[ix] = diff.result(); } } img.apply( &Plane::normalize ); return img; }
void AScrollBar::_Change(int iSize) { //iSize代表的是VirtualSize中的对应大小 if( iSize == 0 ) return; int pos = (int)GetPosition(); if( pos + iSize < 0 ) iSize = -pos; else if( pos + iSize > (int)GetRange() ) iSize = (int)GetRange() - pos; int iDeltaPosition=iSize; SetPosition(pos + iSize); AMouseEvent evt; evt.m_Delta = iDeltaPosition; OnScroll.Call(this,&evt); AContainer* pc = dynamic_cast<AContainer*>(GetParent()); if( pc ) { pc->DoLayout(); } }
Plane PlaneRender::renderPlane( const AContainer& aligner, int plane, AProcessWatcher* watcher ) const{ auto scale = aligner.image( 0 )[plane].getSize().to<double>() / aligner.image( 0 )[0].getSize().to<double>(); //Create output plane Plane out( (Point<>( aligner.size().size ) * scale).round() ); out.fill( color::BLACK ); //Initialize PlaneItInfos vector<PlaneItInfo> info; info.emplace_back( out, (aligner.size().pos * scale).round() ); for( auto align : aligner ) info.emplace_back( const_cast<Plane&>( align.image()[plane] ), (align.pos() * scale).round() ); //TODO: FIX!!! //Execute MultiPlaneIterator it( info ); it.data = data(); it.iterate_all(); it.for_all_pixels( pixel(), watcher, 1000 * plane ); return out; }
virtual void align( AContainer& container, AProcessWatcher* ) const override { container.resetPosition(); }
Point<double> channelScale( const AContainer& container, unsigned index, unsigned channel ){ return container.image(index)[channel].getSize() / container.image(index).getSize().to<double>(); }
Parameters( const AContainer& container, unsigned index, unsigned channel /*const Plane& background*/ ) : container(container), index(index), channel(channel) /*background(background)*/ { min_point = container.minPoint(); }
bool AWinControlBase::Create() { if( m_pWindow ) return true; InitControls(); m_pWindow = CreateWnd(); if( m_pWindow == NULL ) return false; m_pWindow->AddRef(); HWND hParent = NULL; AControl* pParent = dynamic_cast<AControl*>( GetParent() ); if( pParent ) hParent = pParent->GetUICore()->GetHandle(); if( !m_pWindow->Create(hParent,m_WindowPos) ) { m_pWindow->Release(); m_pWindow = NULL; throw AException(_T("窗口创建失败!")); return false; } AContainer* pcParent = dynamic_cast<AContainer*>(GetParent()); if( pcParent ) pcParent->GetUICore()->AddWatcher(this); //再进行下面的处理 if( m_WindowPos == wpDesign ) { ::SetWindowPos(GetHandle(),HWND_NOTOPMOST,GetLeft(),GetTop(),GetWidth(),GetHeight(),SWP_NOREDRAW|SWP_HIDEWINDOW); } else if( m_WindowPos == wpCenterScreen ) { ARect rScreen; SystemParametersInfo(SPI_GETWORKAREA,0,&rScreen,0); int dw = (rScreen.right-rScreen.left-GetWidth())/2; int dh = (rScreen.bottom-rScreen.top-GetHeight())/2; m_iLeft = (rScreen.left+dw); m_iTop = (rScreen.top+dh); ::SetWindowPos(GetHandle(),HWND_NOTOPMOST,GetLeft(),GetTop(),GetWidth(),GetHeight(),SWP_NOREDRAW|SWP_HIDEWINDOW); } else { ARect r; ::GetWindowRect(GetHandle(),&r); //::SetWindowPos(GetHandle(),HWND_NOTOPMOST,r.left,r.top+1,r.GetWidth(),r.GetHeight(),0); m_iLeft = r.left; m_iTop = r.top; m_iWidth = r.GetWidth(); m_iHeight = r.GetHeight(); } //::SetWindowPos(GetHandle(),HWND_NOTOPMOST,GetLeft(),GetTop(),GetWidth(),GetHeight(),0);//SWP_NOREDRAW|SWP_HIDEWINDOW); //::SetWindowPos(GetHandle(),HWND_NOTOPMOST,GetLeft(),GetTop(),GetWidth(),GetHeight(),SWP_NOREDRAW|SWP_HIDEWINDOW); DoCreate(); ConnectEvent(); DoLayout(); Refresh(); //HRGN hRgn = ::CreateRoundRectRgn(0,0,GetWidth()+1,GetHeight()+1,5,5); //::SetWindowRgn(m_pWindow->GetHandle(),hRgn,FALSE); //::DeleteObject(hRgn); AEvent evt; OnCreate.Call(this,&evt); return true; }
StaticDiff( const AContainer& aligner, const ImageEx& ref, unsigned x, unsigned y ) : aligner(aligner), reference(ref) { offset = QPoint( x, y ); absolute = aligner.size().topLeft(); }
ImageEx AverageRender::render( const AContainer& aligner, AProcessWatcher* watcher ) const{ Timer t( "AverageRender::render()" ); //Abort if no images if( aligner.count() == 0 ){ qWarning( "No images to render!" ); return ImageEx(); } unsigned planes_amount = for_merging ? 1 : aligner.image(0).size(); ProgressWrapper( watcher ).setTotal( aligner.count() * planes_amount ); //Determine if we need to care about alpha per plane bool use_plane_alpha = false; for( unsigned i=0; i<aligner.count(); ++i ) if( aligner.alpha( i ) || aligner.imageMask( i ) >= 0 ){ use_plane_alpha = true; break; } //Check for movement in both direction auto movement = aligner.hasMovement(); if( movement.first && movement.second ) use_plane_alpha = true; auto color_space = aligner.image(0).getColorSpace(); ImageEx img( for_merging ? color_space.changed( Transform::GRAY ) : color_space ); AlphaScales masks; for( unsigned c=0; c<planes_amount; c++ ){ auto scale = upscale_chroma ? Point<double>(1,1) : aligner.image( 0 )[c].getSize().to<double>() / aligner.image( 0 )[0].getSize().to<double>(); masks.addScale( aligner, scale ); } auto min_point = aligner.minPoint(); auto full = aligner.size().size; for( unsigned c=0; c<planes_amount; c++ ){ //Determine local size auto scale = upscale_chroma ? Point<double>(1,1) : aligner.image( 0 )[c].getSize().to<double>() / aligner.image( 0 )[0].getSize().to<double>(); //TODO: something is wrong with the rounding, chroma-channels are slightly off SumPlane sum( (scale * full).ceil() ); sum.spacing = spacing; sum.offset = offset; for( unsigned j=0; j<aligner.count(); j++ ){ auto& image = aligner.image( j ); auto pos = (scale * (aligner.pos(j) - min_point)).round(); auto plane = getScaled( image[c], (scale * image[0].getSize()).round() ); const Plane& alpha_plane = masks.getAlpha( c, aligner.imageMask( j ), aligner.alpha( j ) ); if( use_plane_alpha && alpha_plane.valid() ) sum.addAlphaPlane( plane(), alpha_plane, pos ); else sum.addPlane( plane(), pos ); ProgressWrapper( watcher ).add(); } img.addPlane( sum.average() ); if( c == 0 && use_plane_alpha ) img.alpha_plane() = sum.alpha(); //TODO: what to do about the rest? We should try to fill in the gaps? } return img; }