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; }
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; }
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; }
StaticDiff( const AContainer& aligner, const ImageEx& ref, unsigned x, unsigned y ) : aligner(aligner), reference(ref) { offset = QPoint( x, y ); absolute = aligner.size().topLeft(); }