/** // algorithm from ImfRgbaYca.cpp */ void GrFmtExrReader::ChromaToBGR( float *data, int numlines, int step ) { int x, y, t; for( y = 0; y < numlines; y++ ) { for( x = 0; x < m_width; x++ ) { double b, Y, r; if( !m_native_depth ) { b = ((uchar *)data)[y * step + x * 3]; Y = ((uchar *)data)[y * step + x * 3 + 1]; r = ((uchar *)data)[y * step + x * 3 + 2]; } else if( m_type == FLOAT ) { b = data[y * step + x * 3]; Y = data[y * step + x * 3 + 1]; r = data[y * step + x * 3 + 2]; } else { b = ((uint *)data)[y * step + x * 3]; Y = ((uint *)data)[y * step + x * 3 + 1]; r = ((uint *)data)[y * step + x * 3 + 2]; } r = (r + 1) * Y; b = (b + 1) * Y; Y = (Y - b * m_chroma.blue[1] - r * m_chroma.red[1]) / m_chroma.green[1]; if( !m_native_depth ) { int t = cvRound(b); ((uchar *)data)[y * step + x * 3] = CV_CAST_8U(t); t = cvRound(Y); ((uchar *)data)[y * step + x * 3 + 1] = CV_CAST_8U(t); t = cvRound(r); ((uchar *)data)[y * step + x * 3 + 2] = CV_CAST_8U(t); } else if( m_type == FLOAT ) { data[y * step + x * 3] = (float)b; data[y * step + x * 3 + 1] = (float)Y; data[y * step + x * 3 + 2] = (float)r; } else { int t = cvRound(b); ((uint *)data)[y * step + x * 3] = (uint)MAX(t,0); t = cvRound(Y); ((uint *)data)[y * step + x * 3 + 1] = (uint)MAX(t,0); t = cvRound(r); ((uint *)data)[y * step + x * 3 + 2] = (uint)MAX(t,0); } } } }
/* the same with OpenCV */ static int CVT_RGB2YCrCb(const unsigned char *srcImg, int srcStep, unsigned char *dstImg, int dstStep, int width, int height) { #define fix(x,n) (int)((x)*(1 << (n)) + 0.5) #define yuvYr_32f 0.299f #define yuvYg_32f 0.587f #define yuvYb_32f 0.114f #define yuvCr_32f 0.713f #define yuvCb_32f 0.564f #define yuv_shift 14 #define yuvYr fix(yuvYr_32f,14) #define yuvYg fix(yuvYg_32f,14) #define yuvYb fix(yuvYb_32f,14) #define yuvCr fix(yuvCr_32f,14) #define yuvCb fix(yuvCb_32f,14) #define CV_CAST_8U(t) (unsigned char)(!((t) & ~255) ? (t) : (t) > 0 ? 255 : 0) #define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n)) #define yuv_descale(x) CV_DESCALE((x), 14) int res = -1; const unsigned char *pRGB = NULL; unsigned char *pYCrCb = NULL; int y, r, g, b, i,j; __SAM_BEGIN__; if ( (NULL == srcImg) || (NULL == dstImg)) EXIT; for (int i=0; i<height; i++) { pRGB = srcImg + i*srcStep; pYCrCb = dstImg + i*dstStep; for(j=0; j<width; j++) { b = pRGB[j*3+2]; r=pRGB[j*3]; y = yuv_descale(b*yuvYb + yuvYg*pRGB[j*3+1] + yuvYr*r); r = yuv_descale((r-y)*yuvCr) + 128; b = yuv_descale((b-y)*yuvCb) + 128; pYCrCb[j] = CV_CAST_8U(y); pYCrCb[j*3+1] = CV_CAST_8U(r); pYCrCb[j*3+1] = CV_CAST_8U(b); } } res = 0; __SAM_END__; return res; }
bool Jpeg2KDecoder::readComponent8u( uchar *data, void *_buffer, int step, int cmpt, int maxval, int offset, int ncmpts ) { jas_matrix_t* buffer = (jas_matrix_t*)_buffer; jas_image_t* image = (jas_image_t*)m_image; int xstart = jas_image_cmpttlx( image, cmpt ); int xend = jas_image_cmptbrx( image, cmpt ); int xstep = jas_image_cmpthstep( image, cmpt ); int xoffset = jas_image_tlx( image ); int ystart = jas_image_cmpttly( image, cmpt ); int yend = jas_image_cmptbry( image, cmpt ); int ystep = jas_image_cmptvstep( image, cmpt ); int yoffset = jas_image_tly( image ); int x, y, x1, y1, j; int rshift = cvRound(std::log(maxval/256.)/std::log(2.)); int lshift = MAX(0, -rshift); rshift = MAX(0, rshift); int delta = (rshift > 0 ? 1 << (rshift - 1) : 0) + offset; for( y = 0; y < yend - ystart; ) { jas_seqent_t* pix_row = &jas_matrix_get( buffer, y / ystep, 0 ); uchar* dst = data + (y - yoffset) * step - xoffset; if( xstep == 1 ) { if( maxval == 256 && offset == 0 ) for( x = 0; x < xend - xstart; x++ ) { int pix = pix_row[x]; dst[x*ncmpts] = CV_CAST_8U(pix); } else for( x = 0; x < xend - xstart; x++ ) { int pix = ((pix_row[x] + delta) >> rshift) << lshift; dst[x*ncmpts] = CV_CAST_8U(pix); } } else if( xstep == 2 && offset == 0 ) for( x = 0, j = 0; x < xend - xstart; x += 2, j++ ) { int pix = ((pix_row[j] + delta) >> rshift) << lshift; dst[x*ncmpts] = dst[(x+1)*ncmpts] = CV_CAST_8U(pix); } else for( x = 0, j = 0; x < xend - xstart; j++ )
//void YUV2RGB(const unsigned char* Src, unsigned char* Dst, int size, int Y0=0, int U=1, int Y1=2, int V=3) void YUV2RGB(const unsigned char* Src, unsigned char* Dst, int Size, int Y0, int U, int Y1, int V) { int Y, Cr, Cb; int b, g, r; Size *= 2; // YUV¸¦ ±âÁØ for (int i = 0; i < Size; i += 4, Dst += 6 ) { Y = yuv_prescale(Src[i+Y0]); Cb = Src[i+U] - 128; Cr = Src[i+V] - 128; b = yuv_descale( Y + yuvBCb*Cb ); g = yuv_descale( Y + yuvGCr*Cr + yuvGCb*Cb ); r = yuv_descale( Y + yuvRCr*Cr ); Dst[0] = CV_CAST_8U(b); Dst[1] = CV_CAST_8U(g); Dst[2] = CV_CAST_8U(r); Y = yuv_prescale(Src[i+Y1]); Cb = Src[i+U] - 128; Cr = Src[i+V] - 128; b = yuv_descale( Y + yuvBCb*Cb ); g = yuv_descale( Y + yuvGCr*Cr + yuvGCb*Cb ); r = yuv_descale( Y + yuvRCr*Cr ); Dst[3] = CV_CAST_8U(b); Dst[4] = CV_CAST_8U(g); Dst[5] = CV_CAST_8U(r); } }
CV_IMPL void cvFloodFill( CvArr* arr, CvPoint seed_point, CvScalar newVal, CvScalar lo_diff, CvScalar up_diff, CvConnectedComp* comp, int flags, CvArr* maskarr ) { cv::Ptr<CvMat> tempMask; std::vector<CvFFillSegment> buffer; if( comp ) memset( comp, 0, sizeof(*comp) ); int i, type, depth, cn, is_simple; int buffer_size, connectivity = flags & 255; union { uchar b[4]; int i[4]; float f[4]; double _[4]; } nv_buf; nv_buf._[0] = nv_buf._[1] = nv_buf._[2] = nv_buf._[3] = 0; struct { cv::Vec3b b; cv::Vec3i i; cv::Vec3f f; } ld_buf, ud_buf; CvMat stub, *img = cvGetMat(arr, &stub); CvMat maskstub, *mask = (CvMat*)maskarr; CvSize size; type = CV_MAT_TYPE( img->type ); depth = CV_MAT_DEPTH(type); cn = CV_MAT_CN(type); if( connectivity == 0 ) connectivity = 4; else if( connectivity != 4 && connectivity != 8 ) CV_Error( CV_StsBadFlag, "Connectivity must be 4, 0(=4) or 8" ); is_simple = mask == 0 && (flags & CV_FLOODFILL_MASK_ONLY) == 0; for( i = 0; i < cn; i++ ) { if( lo_diff.val[i] < 0 || up_diff.val[i] < 0 ) CV_Error( CV_StsBadArg, "lo_diff and up_diff must be non-negative" ); is_simple &= fabs(lo_diff.val[i]) < DBL_EPSILON && fabs(up_diff.val[i]) < DBL_EPSILON; } size = cvGetMatSize( img ); if( (unsigned)seed_point.x >= (unsigned)size.width || (unsigned)seed_point.y >= (unsigned)size.height ) CV_Error( CV_StsOutOfRange, "Seed point is outside of image" ); cvScalarToRawData( &newVal, &nv_buf, type, 0 ); buffer_size = MAX( size.width, size.height ) * 2; buffer.resize( buffer_size ); if( is_simple ) { int elem_size = CV_ELEM_SIZE(type); const uchar* seed_ptr = img->data.ptr + img->step*seed_point.y + elem_size*seed_point.x; for(i = 0; i < elem_size; i++) if (seed_ptr[i] != nv_buf.b[i]) break; if (i != elem_size) { if( type == CV_8UC1 ) icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, nv_buf.b[0], comp, flags, &buffer); else if( type == CV_8UC3 ) icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, cv::Vec3b(nv_buf.b), comp, flags, &buffer); else if( type == CV_32SC1 ) icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, nv_buf.i[0], comp, flags, &buffer); else if( type == CV_32FC1 ) icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, nv_buf.f[0], comp, flags, &buffer); else if( type == CV_32SC3 ) icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, cv::Vec3i(nv_buf.i), comp, flags, &buffer); else if( type == CV_32FC3 ) icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, cv::Vec3f(nv_buf.f), comp, flags, &buffer); else CV_Error( CV_StsUnsupportedFormat, "" ); return; } } if( !mask ) { /* created mask will be 8-byte aligned */ tempMask = cvCreateMat( size.height + 2, (size.width + 9) & -8, CV_8UC1 ); mask = tempMask; } else { mask = cvGetMat( mask, &maskstub ); if( !CV_IS_MASK_ARR( mask )) CV_Error( CV_StsBadMask, "" ); if( mask->width != size.width + 2 || mask->height != size.height + 2 ) CV_Error( CV_StsUnmatchedSizes, "mask must be 2 pixel wider " "and 2 pixel taller than filled image" ); } int width = tempMask ? mask->step : size.width + 2; uchar* mask_row = mask->data.ptr + mask->step; memset( mask_row - mask->step, 1, width ); for( i = 1; i <= size.height; i++, mask_row += mask->step ) { if( tempMask ) memset( mask_row, 0, width ); mask_row[0] = mask_row[size.width+1] = (uchar)1; } memset( mask_row, 1, width ); if( depth == CV_8U ) for( i = 0; i < cn; i++ ) { int t = cvFloor(lo_diff.val[i]); ld_buf.b[i] = CV_CAST_8U(t); t = cvFloor(up_diff.val[i]); ud_buf.b[i] = CV_CAST_8U(t); } else if( depth == CV_32S ) for( i = 0; i < cn; i++ ) { int t = cvFloor(lo_diff.val[i]); ld_buf.i[i] = t; t = cvFloor(up_diff.val[i]); ud_buf.i[i] = t; } else if( depth == CV_32F ) for( i = 0; i < cn; i++ ) { ld_buf.f[i] = (float)lo_diff.val[i]; ud_buf.f[i] = (float)up_diff.val[i]; } else CV_Error( CV_StsUnsupportedFormat, "" ); if( type == CV_8UC1 ) icvFloodFillGrad_CnIR<uchar, int, Diff8uC1>( img->data.ptr, img->step, mask->data.ptr, mask->step, size, seed_point, nv_buf.b[0], Diff8uC1(ld_buf.b[0], ud_buf.b[0]), comp, flags, &buffer); else if( type == CV_8UC3 ) icvFloodFillGrad_CnIR<cv::Vec3b, cv::Vec3i, Diff8uC3>( img->data.ptr, img->step, mask->data.ptr, mask->step, size, seed_point, cv::Vec3b(nv_buf.b), Diff8uC3(ld_buf.b, ud_buf.b), comp, flags, &buffer); else if( type == CV_32SC1 ) icvFloodFillGrad_CnIR<int, int, Diff32sC1>( img->data.ptr, img->step, mask->data.ptr, mask->step, size, seed_point, nv_buf.i[0], Diff32sC1(ld_buf.i[0], ud_buf.i[0]), comp, flags, &buffer); else if( type == CV_32SC3 ) icvFloodFillGrad_CnIR<cv::Vec3i, cv::Vec3i, Diff32sC3>( img->data.ptr, img->step, mask->data.ptr, mask->step, size, seed_point, cv::Vec3i(nv_buf.i), Diff32sC3(ld_buf.i, ud_buf.i), comp, flags, &buffer); else if( type == CV_32FC1 ) icvFloodFillGrad_CnIR<float, float, Diff32fC1>( img->data.ptr, img->step, mask->data.ptr, mask->step, size, seed_point, nv_buf.f[0], Diff32fC1(ld_buf.f[0], ud_buf.f[0]), comp, flags, &buffer); else if( type == CV_32FC3 ) icvFloodFillGrad_CnIR<cv::Vec3f, cv::Vec3f, Diff32fC3>( img->data.ptr, img->step, mask->data.ptr, mask->step, size, seed_point, cv::Vec3f(nv_buf.f), Diff32fC3(ld_buf.f, ud_buf.f), comp, flags, &buffer); else CV_Error(CV_StsUnsupportedFormat, ""); }
dst[x* ncmpts] = CV_CAST_8U(pix); } else for (x = 0; x < xend - xstart; x++) { int pix = ((pix_row[x] + delta) >> rshift) << lshift; dst[x* ncmpts] = CV_CAST_8U(pix); } } else if (xstep == 2 && offset == 0) for (x = 0, j = 0; x < xend - xstart; x += 2, j++) { int pix = ((pix_row[j] + delta) >> rshift) << lshift; dst[x* ncmpts] = dst[(x+1)*ncmpts] = CV_CAST_8U(pix); } else for (x = 0, j = 0; x < xend - xstart; j++) { int pix = ((pix_row[j] + delta) >> rshift) << lshift; pix = CV_CAST_8U(pix); for (x1 = x + xstep; x < x1; x++) { dst[x* ncmpts] = (uchar)pix; } } y1 = y + ystep; for (++y; y < y1; y++, dst += step) for (x = 0; x < xend - xstart; x++) { dst[x* ncmpts + step] = dst[x*ncmpts]; } } return true; }
static void cvTsThreshold( const CvMat* _src, CvMat* _dst, float thresh, float maxval, int thresh_type ) { int i, j; int depth = CV_MAT_DEPTH(_src->type), cn = CV_MAT_CN(_src->type); int width_n = _src->cols*cn, height = _src->rows; int ithresh = cvFloor(thresh), ithresh2, imaxval = cvRound(maxval); const uchar* src = _src->data.ptr; uchar* dst = _dst->data.ptr; ithresh2 = CV_CAST_8U(ithresh); imaxval = CV_CAST_8U(imaxval); assert( depth == CV_8U || depth == CV_32F ); switch( thresh_type ) { case CV_THRESH_BINARY: for( i = 0; i < height; i++, src += _src->step, dst += _dst->step ) { if( depth == CV_8U ) for( j = 0; j < width_n; j++ ) dst[j] = (uchar)(src[j] > ithresh ? imaxval : 0); else for( j = 0; j < width_n; j++ ) ((float*)dst)[j] = ((const float*)src)[j] > thresh ? maxval : 0.f; } break; case CV_THRESH_BINARY_INV: for( i = 0; i < height; i++, src += _src->step, dst += _dst->step ) { if( depth == CV_8U ) for( j = 0; j < width_n; j++ ) dst[j] = (uchar)(src[j] > ithresh ? 0 : imaxval); else for( j = 0; j < width_n; j++ ) ((float*)dst)[j] = ((const float*)src)[j] > thresh ? 0.f : maxval; } break; case CV_THRESH_TRUNC: for( i = 0; i < height; i++, src += _src->step, dst += _dst->step ) { if( depth == CV_8U ) for( j = 0; j < width_n; j++ ) { int s = src[j]; dst[j] = (uchar)(s > ithresh ? ithresh2 : s); } else for( j = 0; j < width_n; j++ ) { float s = ((const float*)src)[j]; ((float*)dst)[j] = s > thresh ? thresh : s; } } break; case CV_THRESH_TOZERO: for( i = 0; i < height; i++, src += _src->step, dst += _dst->step ) { if( depth == CV_8U ) for( j = 0; j < width_n; j++ ) { int s = src[j]; dst[j] = (uchar)(s > ithresh ? s : 0); } else for( j = 0; j < width_n; j++ ) { float s = ((const float*)src)[j]; ((float*)dst)[j] = s > thresh ? s : 0.f; } } break; case CV_THRESH_TOZERO_INV: for( i = 0; i < height; i++, src += _src->step, dst += _dst->step ) { if( depth == CV_8U ) for( j = 0; j < width_n; j++ ) { int s = src[j]; dst[j] = (uchar)(s > ithresh ? 0 : s); } else for( j = 0; j < width_n; j++ ) { float s = ((const float*)src)[j]; ((float*)dst)[j] = s > thresh ? 0.f : s; } } break; default: assert(0); } }
// //USAGE: ch9_background startFrameCollection# endFrameCollection# [movie filename, else from camera] //If from AVI, then optionally add HighAvg, LowAvg, HighCB_Y LowCB_Y HighCB_U LowCB_U HighCB_V LowCB_V // int main(int argc, char** argv) { const char* filename = 0; IplImage* rawImage = 0, *yuvImage = 0; //yuvImage is for codebook method IplImage *ImaskCodeBook = 0,*ImaskCodeBookCC = 0; CvCapture* capture = 0; int c, n, nframes = 0; int nframesToLearnBG = 300; model = cvCreateBGCodeBookModel(); //Set color thresholds to default values model->modMin[0] = 3; model->modMin[1] = model->modMin[2] = 3; model->modMax[0] = 10; model->modMax[1] = model->modMax[2] = 10; model->cbBounds[0] = model->cbBounds[1] = model->cbBounds[2] = 10; bool pause = false; bool singlestep = false; for( n = 1; n < argc; n++ ) { static const char* nframesOpt = "--nframes="; if( strncmp(argv[n], nframesOpt, strlen(nframesOpt))==0 ) { if( sscanf(argv[n] + strlen(nframesOpt), "%d", &nframesToLearnBG) == 0 ) { help(); return -1; } } else filename = argv[n]; } if( !filename ) { printf("Capture from camera\n"); capture = cvCaptureFromCAM( 0 ); } else { printf("Capture from file %s\n",filename); capture = cvCreateFileCapture( filename ); } if( !capture ) { printf( "Can not initialize video capturing\n\n" ); help(); return -1; } //MAIN PROCESSING LOOP: for(;;) { if( !pause ) { rawImage = cvQueryFrame( capture ); ++nframes; if(!rawImage) break; } if( singlestep ) pause = true; //First time: if( nframes == 1 && rawImage ) { // CODEBOOK METHOD ALLOCATION yuvImage = cvCloneImage(rawImage); ImaskCodeBook = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 ); ImaskCodeBookCC = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 ); cvSet(ImaskCodeBook,cvScalar(255)); cvNamedWindow( "Raw", 1 ); cvNamedWindow( "ForegroundCodeBook",1); cvNamedWindow( "CodeBook_ConnectComp",1); } // If we've got an rawImage and are good to go: if( rawImage ) { cvCvtColor( rawImage, yuvImage, CV_BGR2YCrCb );//YUV For codebook method //This is where we build our background model if( !pause && nframes-1 < nframesToLearnBG ) cvBGCodeBookUpdate( model, yuvImage ); if( nframes-1 == nframesToLearnBG ) cvBGCodeBookClearStale( model, model->t/2 ); //Find the foreground if any if( nframes-1 >= nframesToLearnBG ) { // Find foreground by codebook method cvBGCodeBookDiff( model, yuvImage, ImaskCodeBook ); // This part just to visualize bounding boxes and centers if desired cvCopy(ImaskCodeBook,ImaskCodeBookCC); cvSegmentFGMask( ImaskCodeBookCC ); //bwareaopen_(ImaskCodeBookCC,100); cvShowImage( "CodeBook_ConnectComp",ImaskCodeBookCC); detect(ImaskCodeBookCC,rawImage); } //Display cvShowImage( "Raw", rawImage ); cvShowImage( "ForegroundCodeBook",ImaskCodeBook); } // User input: c = cvWaitKey(10)&0xFF; c = tolower(c); // End processing on ESC, q or Q if(c == 27 || c == 'q') break; //Else check for user input switch( c ) { case 'h': help(); break; case 'p': pause = !pause; break; case 's': singlestep = !singlestep; pause = false; break; case 'r': pause = false; singlestep = false; break; case ' ': cvBGCodeBookClearStale( model, 0 ); nframes = 0; break; //CODEBOOK PARAMS case 'y': case '0': case 'u': case '1': case 'v': case '2': case 'a': case '3': case 'b': ch[0] = c == 'y' || c == '0' || c == 'a' || c == '3'; ch[1] = c == 'u' || c == '1' || c == 'a' || c == '3' || c == 'b'; ch[2] = c == 'v' || c == '2' || c == 'a' || c == '3' || c == 'b'; printf("CodeBook YUV Channels active: %d, %d, %d\n", ch[0], ch[1], ch[2] ); break; case 'i': //modify max classification bounds (max bound goes higher) case 'o': //modify max classification bounds (max bound goes lower) case 'k': //modify min classification bounds (min bound goes lower) case 'l': //modify min classification bounds (min bound goes higher) { uchar* ptr = c == 'i' || c == 'o' ? model->modMax : model->modMin; for(n=0; n<NCHANNELS; n++) { if( ch[n] ) { int v = ptr[n] + (c == 'i' || c == 'l' ? 1 : -1); ptr[n] = CV_CAST_8U(v); } printf("%d,", ptr[n]); } printf(" CodeBook %s Side\n", c == 'i' || c == 'o' ? "High" : "Low" ); } break; } } cvReleaseCapture( &capture ); cvDestroyWindow( "Raw" ); cvDestroyWindow( "ForegroundCodeBook"); cvDestroyWindow( "CodeBook_ConnectComp"); return 0; }
CV_IMPL double cvThreshold( const void* srcarr, void* dstarr, double thresh, double maxval, int type ) { CvHistogram* hist = 0; CV_FUNCNAME( "cvThreshold" ); __BEGIN__; CvSize roi; int src_step, dst_step; CvMat src_stub, *src = (CvMat*)srcarr; CvMat dst_stub, *dst = (CvMat*)dstarr; CvMat src0, dst0; int coi1 = 0, coi2 = 0; int ithresh, imaxval, cn; bool use_otsu; CV_CALL( src = cvGetMat( src, &src_stub, &coi1 )); CV_CALL( dst = cvGetMat( dst, &dst_stub, &coi2 )); if( coi1 + coi2 ) CV_ERROR( CV_BadCOI, "COI is not supported by the function" ); if( !CV_ARE_CNS_EQ( src, dst ) ) CV_ERROR( CV_StsUnmatchedFormats, "Both arrays must have equal number of channels" ); cn = CV_MAT_CN(src->type); if( cn > 1 ) { src = cvReshape( src, &src0, 1 ); dst = cvReshape( dst, &dst0, 1 ); } use_otsu = (type & ~CV_THRESH_MASK) == CV_THRESH_OTSU; type &= CV_THRESH_MASK; if( use_otsu ) { float _ranges[] = { 0, 256 }; float* ranges = _ranges; int hist_size = 256; void* srcarr0 = src; if( CV_MAT_TYPE(src->type) != CV_8UC1 ) CV_ERROR( CV_StsNotImplemented, "Otsu method can only be used with 8uC1 images" ); CV_CALL( hist = cvCreateHist( 1, &hist_size, CV_HIST_ARRAY, &ranges )); cvCalcArrHist( &srcarr0, hist ); thresh = cvFloor(icvGetThreshVal_Otsu( hist )); } if( !CV_ARE_DEPTHS_EQ( src, dst ) ) { if( CV_MAT_TYPE(dst->type) != CV_8UC1 ) CV_ERROR( CV_StsUnsupportedFormat, "In case of different types destination should be 8uC1" ); if( type != CV_THRESH_BINARY && type != CV_THRESH_BINARY_INV ) CV_ERROR( CV_StsBadArg, "In case of different types only CV_THRESH_BINARY " "and CV_THRESH_BINARY_INV thresholding types are supported" ); if( maxval < 0 ) { CV_CALL( cvSetZero( dst )); } else { CV_CALL( cvCmpS( src, thresh, dst, type == CV_THRESH_BINARY ? CV_CMP_GT : CV_CMP_LE )); if( maxval < 255 ) CV_CALL( cvAndS( dst, cvScalarAll( maxval ), dst )); } EXIT; } if( !CV_ARE_SIZES_EQ( src, dst ) ) CV_ERROR( CV_StsUnmatchedSizes, "" ); roi = cvGetMatSize( src ); if( CV_IS_MAT_CONT( src->type & dst->type )) { roi.width *= roi.height; roi.height = 1; src_step = dst_step = CV_STUB_STEP; } else { src_step = src->step; dst_step = dst->step; } switch( CV_MAT_DEPTH(src->type) ) { case CV_8U: ithresh = cvFloor(thresh); imaxval = cvRound(maxval); if( type == CV_THRESH_TRUNC ) imaxval = ithresh; imaxval = CV_CAST_8U(imaxval); if( ithresh < 0 || ithresh >= 255 ) { if( type == CV_THRESH_BINARY || type == CV_THRESH_BINARY_INV || ((type == CV_THRESH_TRUNC || type == CV_THRESH_TOZERO_INV) && ithresh < 0) || (type == CV_THRESH_TOZERO && ithresh >= 255) ) { int v = type == CV_THRESH_BINARY ? (ithresh >= 255 ? 0 : imaxval) : type == CV_THRESH_BINARY_INV ? (ithresh >= 255 ? imaxval : 0) : type == CV_THRESH_TRUNC ? imaxval : 0; cvSet( dst, cvScalarAll(v) ); EXIT; } else { cvCopy( src, dst ); EXIT; } } if( type == CV_THRESH_BINARY || type == CV_THRESH_BINARY_INV ) { if( icvCompareC_8u_C1R_cv_p && icvAndC_8u_C1R_p ) { IPPI_CALL( icvCompareC_8u_C1R_cv_p( src->data.ptr, src_step, (uchar)ithresh, dst->data.ptr, dst_step, roi, type == CV_THRESH_BINARY ? cvCmpGreater : cvCmpLessEq )); if( imaxval < 255 ) IPPI_CALL( icvAndC_8u_C1R_p( dst->data.ptr, dst_step, (uchar)imaxval, dst->data.ptr, dst_step, roi )); EXIT; } } else if( type == CV_THRESH_TRUNC || type == CV_THRESH_TOZERO_INV ) { if( icvThreshold_GTVal_8u_C1R_p ) { IPPI_CALL( icvThreshold_GTVal_8u_C1R_p( src->data.ptr, src_step, dst->data.ptr, dst_step, roi, (uchar)ithresh, (uchar)(type == CV_THRESH_TRUNC ? ithresh : 0) )); EXIT; } } else { assert( type == CV_THRESH_TOZERO ); if( icvThreshold_LTVal_8u_C1R_p ) { ithresh = cvFloor(thresh+1.); ithresh = CV_CAST_8U(ithresh); IPPI_CALL( icvThreshold_LTVal_8u_C1R_p( src->data.ptr, src_step, dst->data.ptr, dst_step, roi, (uchar)ithresh, 0 )); EXIT; } } icvThresh_8u_C1R( src->data.ptr, src_step, dst->data.ptr, dst_step, roi, (uchar)ithresh, (uchar)imaxval, type ); break; case CV_32F: if( type == CV_THRESH_TRUNC || type == CV_THRESH_TOZERO_INV ) { if( icvThreshold_GTVal_32f_C1R_p ) { IPPI_CALL( icvThreshold_GTVal_32f_C1R_p( src->data.fl, src_step, dst->data.fl, dst_step, roi, (float)thresh, type == CV_THRESH_TRUNC ? (float)thresh : 0 )); EXIT; } } else if( type == CV_THRESH_TOZERO ) { if( icvThreshold_LTVal_32f_C1R_p ) { IPPI_CALL( icvThreshold_LTVal_32f_C1R_p( src->data.fl, src_step, dst->data.fl, dst_step, roi, (float)(thresh*(1 + FLT_EPSILON)), 0 )); EXIT; } } icvThresh_32f_C1R( src->data.fl, src_step, dst->data.fl, dst_step, roi, (float)thresh, (float)maxval, type ); break; default: CV_ERROR( CV_BadDepth, cvUnsupportedFormat ); } __END__; if( hist ) cvReleaseHist( &hist ); return thresh; }
// convert CvScalar to specified type void cvScalarToRawData( CvScalar* scalar, int flags, void* data, int extend_to_12 ) { CV_FUNCNAME( "cvScalarToRawData" ); __BEGIN__; int type = CV_ARR_TYPE( flags ); int cn = CV_ARR_CN( type ); int depth = type & CV_ARR_DEPTH_MASK; assert( scalar && data ); assert( (unsigned)(cn - 1) < 4 ); switch( depth ) { case CV_8UC1: while( cn-- ) { int t = cvRound( scalar->val[cn] ); ((uchar*)data)[cn] = CV_CAST_8U(t); } break; case CV_8SC1: while( cn-- ) { int t = cvRound( scalar->val[cn] ); ((char*)data)[cn] = CV_CAST_8S(t); } break; case CV_16SC1: while( cn-- ) { int t = cvRound( scalar->val[cn] ); ((short*)data)[cn] = CV_CAST_16S(t); } break; case CV_32SC1: while( cn-- ) ((int*)data)[cn] = cvRound( scalar->val[cn] ); break; case CV_32FC1: while( cn-- ) ((float*)data)[cn] = (float)(scalar->val[cn]); break; case CV_64FC1: while( cn-- ) ((double*)data)[cn] = (double)(scalar->val[cn]); break; default: assert(0); CV_ERROR_FROM_CODE( CV_BadDepth ); } if( extend_to_12 ) { int pix_size = icvPixSize[type]; int offset = icvPixSize[depth]*12; do { offset -= pix_size; memcpy( (char*)data + offset, data, pix_size ); } while( offset > pix_size ); } __END__; }
/* 8-bit grayscale distance transform function */ static void icvDistanceATS_L1_8u( const CvMat* src, CvMat* dst ) { int width = src->cols, height = src->rows; int a; uchar lut[256]; int x, y; const uchar *sbase = src->data.ptr; uchar *dbase = dst->data.ptr; int srcstep = src->step; int dststep = dst->step; CV_Assert( CV_IS_MASK_ARR( src ) && CV_MAT_TYPE( dst->type ) == CV_8UC1 ); CV_Assert( CV_ARE_SIZES_EQ( src, dst )); ////////////////////// forward scan //////////////////////// for( x = 0; x < 256; x++ ) lut[x] = CV_CAST_8U(x+1); //init first pixel to max (we're going to be skipping it) dbase[0] = (uchar)(sbase[0] == 0 ? 0 : 255); //first row (scan west only, skip first pixel) for( x = 1; x < width; x++ ) dbase[x] = (uchar)(sbase[x] == 0 ? 0 : lut[dbase[x-1]]); for( y = 1; y < height; y++ ) { sbase += srcstep; dbase += dststep; //for left edge, scan north only a = sbase[0] == 0 ? 0 : lut[dbase[-dststep]]; dbase[0] = (uchar)a; for( x = 1; x < width; x++ ) { a = sbase[x] == 0 ? 0 : lut[MIN(a, dbase[x - dststep])]; dbase[x] = (uchar)a; } } ////////////////////// backward scan /////////////////////// a = dbase[width-1]; // do last row east pixel scan here (skip bottom right pixel) for( x = width - 2; x >= 0; x-- ) { a = lut[a]; dbase[x] = (uchar)(CV_CALC_MIN_8U(a, dbase[x])); } // right edge is the only error case for( y = height - 2; y >= 0; y-- ) { dbase -= dststep; // do right edge a = lut[dbase[width-1+dststep]]; dbase[width-1] = (uchar)(MIN(a, dbase[width-1])); for( x = width - 2; x >= 0; x-- ) { int b = dbase[x+dststep]; a = lut[MIN(a, b)]; dbase[x] = (uchar)(MIN(a, dbase[x])); } } }
bool GrFmtExrReader::ReadData( uchar* data, int step, int color ) { bool justcopy = m_native_depth; bool chromatorgb = false; bool rgbtogray = false; bool result = true; FrameBuffer frame; int xsample[3] = {1, 1, 1}; char *buffer; int xstep; int ystep; xstep = m_native_depth ? 4 : 1; if( !m_native_depth || (!color && m_iscolor )) { buffer = (char *)new float[ m_width * 3 ]; ystep = 0; } else { buffer = (char *)data; ystep = step; } if( m_ischroma ) { if( color ) { if( m_iscolor ) { if( m_blue ) { frame.insert( "BY", Slice( m_type, buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep, 12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 )); xsample[0] = m_blue->ySampling; } if( m_green ) { frame.insert( "Y", Slice( m_type, buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4, 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); xsample[1] = m_green->ySampling; } if( m_red ) { frame.insert( "RY", Slice( m_type, buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8, 12, ystep, m_red->xSampling, m_red->ySampling, 0.0 )); xsample[2] = m_red->ySampling; } chromatorgb = true; } else { frame.insert( "Y", Slice( m_type, buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep, 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); frame.insert( "Y", Slice( m_type, buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4, 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); frame.insert( "Y", Slice( m_type, buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8, 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); xsample[0] = m_green->ySampling; xsample[1] = m_green->ySampling; xsample[2] = m_green->ySampling; } } else { frame.insert( "Y", Slice( m_type, buffer - m_datawindow.min.x * 4 - m_datawindow.min.y * ystep, 4, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); xsample[0] = m_green->ySampling; } } else { if( m_blue ) { frame.insert( "B", Slice( m_type, buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep, 12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 )); xsample[0] = m_blue->ySampling; } if( m_green ) { frame.insert( "G", Slice( m_type, buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4, 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 )); xsample[1] = m_green->ySampling; } if( m_red ) { frame.insert( "R", Slice( m_type, buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8, 12, ystep, m_red->xSampling, m_red->ySampling, 0.0 )); xsample[2] = m_red->ySampling; } if(color == 0) { rgbtogray = true; justcopy = false; } } m_file->setFrameBuffer( frame ); if( justcopy ) { m_file->readPixels( m_datawindow.min.y, m_datawindow.max.y ); if( color ) { if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) ) UpSample( data, 3, step / xstep, xsample[0], m_blue->ySampling ); if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) ) UpSample( data + xstep, 3, step / xstep, xsample[1], m_green->ySampling ); if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) ) UpSample( data + 2 * xstep, 3, step / xstep, xsample[2], m_red->ySampling ); } else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) ) UpSample( data, 1, step / xstep, xsample[0], m_green->ySampling ); } else { uchar *out = data; int x, y; for( y = m_datawindow.min.y; y <= m_datawindow.max.y; y++ ) { m_file->readPixels( y, y ); if( rgbtogray ) { if( xsample[0] != 1 ) UpSampleX( (float *)buffer, 3, xsample[0] ); if( xsample[1] != 1 ) UpSampleX( (float *)buffer + 4, 3, xsample[1] ); if( xsample[2] != 1 ) UpSampleX( (float *)buffer + 8, 3, xsample[2] ); RGBToGray( (float *)buffer, (float *)out ); } else { if( xsample[0] != 1 ) UpSampleX( (float *)buffer, 3, xsample[0] ); if( xsample[1] != 1 ) UpSampleX( (float *)(buffer + 4), 3, xsample[1] ); if( xsample[2] != 1 ) UpSampleX( (float *)(buffer + 8), 3, xsample[2] ); if( chromatorgb ) ChromaToBGR( (float *)buffer, 1, step ); if( m_type == FLOAT ) { float *fi = (float *)buffer; for( x = 0; x < m_width * 3; x++) { int t = cvRound(fi[x]*5); out[x] = CV_CAST_8U(t); } } else { uint *ui = (uint *)buffer; for( x = 0; x < m_width * 3; x++) { uint t = ui[x]; out[x] = CV_CAST_8U(t); } } } out += step; } if( color ) { if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) ) UpSampleY( data, 3, step / xstep, m_blue->ySampling ); if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) ) UpSampleY( data + xstep, 3, step / xstep, m_green->ySampling ); if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) ) UpSampleY( data + 2 * xstep, 3, step / xstep, m_red->ySampling ); } else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) ) UpSampleY( data, 1, step / xstep, m_green->ySampling ); } if( chromatorgb ) ChromaToBGR( (float *)data, m_height, step / xstep ); Close(); return result; }
CV_IMPL void cvFloodFill( CvArr* arr, CvPoint seed_point, CvScalar newVal, CvScalar lo_diff, CvScalar up_diff, CvConnectedComp* comp, int flags, CvArr* maskarr ) { static void* ffill_tab[4]; static void* ffillgrad_tab[4]; static int inittab = 0; CvMat* tempMask = 0; CvFFillSegment* buffer = 0; CV_FUNCNAME( "cvFloodFill" ); if( comp ) memset( comp, 0, sizeof(*comp) ); __BEGIN__; int i, type, depth, cn, is_simple, idx; int buffer_size, connectivity = flags & 255; double nv_buf[4] = {0,0,0,0}; union { uchar b[4]; float f[4]; } ld_buf, ud_buf; CvMat stub, *img = (CvMat*)arr; CvMat maskstub, *mask = (CvMat*)maskarr; CvSize size; if( !inittab ) { icvInitFloodFill( ffill_tab, ffillgrad_tab ); inittab = 1; } CV_CALL( img = cvGetMat( img, &stub )); type = CV_MAT_TYPE( img->type ); depth = CV_MAT_DEPTH(type); cn = CV_MAT_CN(type); idx = type == CV_8UC1 || type == CV_8UC3 ? 0 : type == CV_32FC1 || type == CV_32FC3 ? 1 : -1; if( idx < 0 ) CV_ERROR( CV_StsUnsupportedFormat, "" ); if( connectivity == 0 ) connectivity = 4; else if( connectivity != 4 && connectivity != 8 ) CV_ERROR( CV_StsBadFlag, "Connectivity must be 4, 0(=4) or 8" ); is_simple = mask == 0 && (flags & CV_FLOODFILL_MASK_ONLY) == 0; for( i = 0; i < cn; i++ ) { if( lo_diff.val[i] < 0 || up_diff.val[i] < 0 ) CV_ERROR( CV_StsBadArg, "lo_diff and up_diff must be non-negative" ); is_simple &= fabs(lo_diff.val[i]) < DBL_EPSILON && fabs(up_diff.val[i]) < DBL_EPSILON; } size = cvGetMatSize( img ); if( (unsigned)seed_point.x >= (unsigned)size.width || (unsigned)seed_point.y >= (unsigned)size.height ) CV_ERROR( CV_StsOutOfRange, "Seed point is outside of image" ); cvScalarToRawData( &newVal, &nv_buf, type, 0 ); buffer_size = MAX( size.width, size.height )*2; CV_CALL( buffer = (CvFFillSegment*)cvAlloc( buffer_size*sizeof(buffer[0]))); if( is_simple ) { CvFloodFillFunc func = (CvFloodFillFunc)ffill_tab[idx]; if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); IPPI_CALL( func( img->data.ptr, img->step, size, seed_point, &nv_buf, comp, flags, buffer, buffer_size, cn )); } else { CvFloodFillGradFunc func = (CvFloodFillGradFunc)ffillgrad_tab[idx]; if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); if( !mask ) { /* created mask will be 8-byte aligned */ tempMask = cvCreateMat( size.height + 2, (size.width + 9) & -8, CV_8UC1 ); mask = tempMask; } else { CV_CALL( mask = cvGetMat( mask, &maskstub )); if( !CV_IS_MASK_ARR( mask )) CV_ERROR( CV_StsBadMask, "" ); if( mask->width != size.width + 2 || mask->height != size.height + 2 ) CV_ERROR( CV_StsUnmatchedSizes, "mask must be 2 pixel wider " "and 2 pixel taller than filled image" ); } { int width = tempMask ? mask->step : size.width + 2; uchar* mask_row = mask->data.ptr + mask->step; memset( mask_row - mask->step, 1, width ); for( i = 1; i <= size.height; i++, mask_row += mask->step ) { if( tempMask ) memset( mask_row, 0, width ); mask_row[0] = mask_row[size.width+1] = (uchar)1; } memset( mask_row, 1, width ); } if( depth == CV_8U ) for( i = 0; i < cn; i++ ) { int t = cvFloor(lo_diff.val[i]); ld_buf.b[i] = CV_CAST_8U(t); t = cvFloor(up_diff.val[i]); ud_buf.b[i] = CV_CAST_8U(t); } else for( i = 0; i < cn; i++ ) { ld_buf.f[i] = (float)lo_diff.val[i]; ud_buf.f[i] = (float)up_diff.val[i]; } IPPI_CALL( func( img->data.ptr, img->step, mask->data.ptr, mask->step, size, seed_point, &nv_buf, ld_buf.f, ud_buf.f, comp, flags, buffer, buffer_size, cn )); } __END__; cvFree( &buffer ); cvReleaseMat( &tempMask ); }
static void cvTsCalcBackProject( IplImage** images, IplImage* dst, CvHistogram* hist, int* channels ) { int x, y, k, cdims; union { float* fl; uchar* ptr; } plane[CV_MAX_DIM]; int nch[CV_MAX_DIM]; int dims[CV_MAX_DIM]; int uniform = CV_IS_UNIFORM_HIST(hist); CvSize img_size = cvGetSize(images[0]); int img_depth = images[0]->depth; cdims = cvGetDims( hist->bins, dims ); for( k = 0; k < cdims; k++ ) nch[k] = images[k]->nChannels; for( y = 0; y < img_size.height; y++ ) { if( img_depth == IPL_DEPTH_8U ) for( k = 0; k < cdims; k++ ) plane[k].ptr = &CV_IMAGE_ELEM(images[k], uchar, y, 0 ) + channels[k]; else for( k = 0; k < cdims; k++ ) plane[k].fl = &CV_IMAGE_ELEM(images[k], float, y, 0 ) + channels[k]; for( x = 0; x < img_size.width; x++ ) { float val[CV_MAX_DIM]; float bin_val = 0; int idx[CV_MAX_DIM]; if( img_depth == IPL_DEPTH_8U ) for( k = 0; k < cdims; k++ ) val[k] = plane[k].ptr[x*nch[k]]; else for( k = 0; k < cdims; k++ ) val[k] = plane[k].fl[x*nch[k]]; idx[cdims-1] = -1; if( uniform ) { for( k = 0; k < cdims; k++ ) { double v = val[k], lo = hist->thresh[k][0], hi = hist->thresh[k][1]; idx[k] = cvFloor((v - lo)*dims[k]/(hi - lo)); if( idx[k] < 0 || idx[k] >= dims[k] ) break; } } else { for( k = 0; k < cdims; k++ ) { float v = val[k]; float* t = hist->thresh2[k]; int j, n = dims[k]; for( j = 0; j <= n; j++ ) if( v < t[j] ) break; if( j <= 0 || j > n ) break; idx[k] = j-1; } } if( k == cdims ) bin_val = (float)cvGetRealND( hist->bins, idx ); if( img_depth == IPL_DEPTH_8U ) { int t = cvRound(bin_val); CV_IMAGE_ELEM( dst, uchar, y, x ) = CV_CAST_8U(t); } else CV_IMAGE_ELEM( dst, float, y, x ) = bin_val; } } }