| 217 | |
| 218 | |
| 219 | ObjectPtr MedianCutSampler::doOperation( const CompoundObject * operands ) |
| 220 | { |
| 221 | ImagePrimitivePtr image = static_cast<ImagePrimitive *>( imageParameter()->getValue() )->copy(); |
| 222 | Box2i dataWindow = image->getDataWindow(); |
| 223 | |
| 224 | // find the right channel |
| 225 | const std::string &channelName = m_channelNameParameter->getTypedValue(); |
| 226 | FloatVectorDataPtr luminance = image->getChannel<float>( channelName ); |
| 227 | if( !luminance ) |
| 228 | { |
| 229 | throw Exception( str( format( "No FloatVectorData channel named \"%s\"." ) % channelName ) ); |
| 230 | } |
| 231 | |
| 232 | // if the projection requires it, weight the luminances so they're less |
| 233 | // important towards the poles of the sphere |
| 234 | Projection projection = (Projection)m_projectionParameter->getNumericValue(); |
| 235 | if( projection==LatLong ) |
| 236 | { |
| 237 | float radiansPerPixel = M_PI / (dataWindow.size().y + 1); |
| 238 | float angle = ( M_PI - radiansPerPixel ) / 2.0f; |
| 239 | |
| 240 | float *p = &(luminance->writable()[0]); |
| 241 | |
| 242 | for( int y=dataWindow.min.y; y<=dataWindow.max.y; y++ ) |
| 243 | { |
| 244 | float *pEnd = p + dataWindow.size().x + 1; |
| 245 | float w = cosf( angle ); |
| 246 | while( p < pEnd ) |
| 247 | { |
| 248 | *p *= w; |
| 249 | p++; |
| 250 | } |
| 251 | angle -= radiansPerPixel; |
| 252 | } |
| 253 | |
| 254 | } |
| 255 | |
| 256 | // make a summed area table for speed |
| 257 | FloatVectorDataPtr summedLuminance = luminance; |
| 258 | luminance = luminance->copy(); // we need this for the centroid computation |
| 259 | |
| 260 | SummedAreaOpPtr summedAreaOp = new SummedAreaOp(); |
| 261 | summedAreaOp->inputParameter()->setValue( image ); |
| 262 | summedAreaOp->copyParameter()->setTypedValue( false ); |
| 263 | summedAreaOp->channelNamesParameter()->getTypedValue().clear(); |
| 264 | summedAreaOp->channelNamesParameter()->getTypedValue().push_back( "Y" ); |
| 265 | summedAreaOp->operate(); |
| 266 | |
| 267 | // do the median cut thing |
| 268 | CompoundObjectPtr result = new CompoundObject; |
| 269 | V2fVectorDataPtr centroids = new V2fVectorData; |
| 270 | Box2iVectorDataPtr areas = new Box2iVectorData; |
| 271 | result->members()["centroids"] = centroids; |
| 272 | result->members()["areas"] = areas; |
| 273 | |
| 274 | dataWindow.max -= dataWindow.min; |
| 275 | dataWindow.min -= dataWindow.min; // let's start indexing from 0 shall we? |
| 276 | Array2D array( &(luminance->writable()[0]), extents[dataWindow.size().x+1][dataWindow.size().y+1], fortran_storage_order() ); |
nothing calls this directly
no test coverage detected