void eng_make_Logical(short *list, int len, int *mmDims, int depth) { std::vector<mwSize> mbDimsVec(depth); std::reverse_copy(mmDims, mmDims+depth, mbDimsVec.begin()); mwSize *mbDims = &mbDimsVec[0]; mxArray *var = mxCreateLogicalArray(depth, mbDims); std::copy(list, list+len, mxGetLogicals(var)); returnHandle(var); }
MxArray::MxArray(const cv::Mat& mat, mxClassID classid, bool transpose) { // handle special case of empty input Mat by creating an empty array classid = (classid == mxUNKNOWN_CLASS) ? ClassIDOf[mat.depth()] : classid; if (mat.empty()) { p_ = mxCreateNumericArray(0, 0, classid, mxREAL); if (!p_) mexErrMsgIdAndTxt("mexopencv:error", "Allocation error"); return; } // transpose cv::Mat if needed cv::Mat input(mat); if (input.dims == 2 && transpose) input = input.t(); // Create a new mxArray (of the specified classID) equivalent to cv::Mat const mwSize nchannels = input.channels(); const int* dims_ = input.size; std::vector<mwSize> d(dims_, dims_ + input.dims); d.push_back(nchannels); std::swap(d[0], d[1]); if (classid == mxLOGICAL_CLASS) { // OpenCV's logical true is any nonzero, while MATLAB's true is 1. cv::compare(input, 0, input, cv::CMP_NE); input.setTo(1, input); p_ = mxCreateLogicalArray(d.size(), &d[0]); } else p_ = mxCreateNumericArray(d.size(), &d[0], classid, mxREAL); if (!p_) mexErrMsgIdAndTxt("mexopencv:error", "Allocation error"); // split input cv::Mat into several single-channel arrays std::vector<cv::Mat> channels; channels.reserve(nchannels); cv::split(input, channels); // Copy each channel from Mat to mxArray (converting to specified classid), // as in: p_(:,:,i) <- cast_to_classid_type(channels[i]) std::vector<mwSize> si(d.size(), 0); // subscript index const int type = CV_MAKETYPE(DepthOf[classid], 1); // destination type for (mwIndex i = 0; i < nchannels; ++i) { si[si.size() - 1] = i; // last dim is a channel index void *ptr = reinterpret_cast<void*>( reinterpret_cast<size_t>(mxGetData(p_)) + mxGetElementSize(p_) * subs(si)); // ptr to i-th channel data cv::Mat m(input.dims, dims_, type, ptr); // only creates Mat header channels[i].convertTo(m, type); // Write to mxArray through m } }
MxArray::MxArray(const cv::Mat& mat, mxClassID classid, bool transpose) { if (mat.empty()) { p_ = mxCreateNumericArray(0, 0, mxDOUBLE_CLASS, mxREAL); if (!p_) mexErrMsgIdAndTxt("mexopencv:error", "Allocation error"); return; } cv::Mat input = (mat.dims == 2 && transpose) ? mat.t() : mat; // Create a new mxArray. const int nchannels = input.channels(); const int* dims_ = input.size; std::vector<mwSize> d(dims_, dims_ + input.dims); d.push_back(nchannels); classid = (classid == mxUNKNOWN_CLASS) ? ClassIDOf[input.depth()] : classid; std::swap(d[0], d[1]); if (classid == mxLOGICAL_CLASS) { // OpenCV's logical true is any nonzero while matlab's true is 1. cv::compare(input, 0, input, cv::CMP_NE); input.setTo(1, input); p_ = mxCreateLogicalArray(d.size(), &d[0]); } else { p_ = mxCreateNumericArray(d.size(), &d[0], classid, mxREAL); } if (!p_) mexErrMsgIdAndTxt("mexopencv:error", "Allocation error"); // Copy each channel. std::vector<cv::Mat> channels; split(input, channels); std::vector<mwSize> si(d.size(), 0); // subscript index. int type = CV_MAKETYPE(DepthOf[classid], 1); // destination type. for (int i = 0; i < nchannels; ++i) { si[si.size() - 1] = i; // last dim is a channel index. void *ptr = reinterpret_cast<void*>( reinterpret_cast<size_t>(mxGetData(p_)) + mxGetElementSize(p_) * subs(si)); cv::Mat m(input.dims, dims_, type, ptr); channels[i].convertTo(m, type); // Write to mxArray through m. } }
static void Segment(const mxArray *mx_in, T lambda, T conv, Gc::Size max_iter, const char *str_nb, const char *str_mf, bool log, mxArray *plhs[]) { // Turn on logging Gc::Examples::Matlab::LogTarget mlt; Gc::System::Log::SetTarget(&mlt); Gc::System::Time::StopWatch::EnableOutput(log); // Get image from matlab Gc::Data::Image<N,T,T> img; Gc::Examples::Matlab::GetImage<N,T,T>(mx_in, img); // Set image resolution - unknown, isotropic img.SetSpacing(Gc::Math::Algebra::Vector<N,T>(1)); // Create neighbourhood object Gc::Energy::Neighbourhood<N,Gc::Int32> nb((Gc::Size)atoi(str_nb + 1), false); // Initialization Gc::Algo::Segmentation::RoussonDeriche::Params<T> rdpar; Gc::Algo::Segmentation::RoussonDeriche::InitialEstimate(img, 50, rdpar); // Grid max-flow Gc::Flow::IGridMaxFlow<N,T,T,T> *mf = Gc::Examples::Matlab::CreateGridMaxFlow<N,T>(str_mf, false); // Segment Gc::System::Collection::Array<N,bool> seg; T energy = Gc::Algo::Segmentation::RoussonDeriche::Compute(img, lambda, rdpar, conv, max_iter, nb, *mf, seg); delete mf; // Save result to matlab plhs[0] = mxCreateLogicalArray(N, mxGetDimensions(mx_in)); Gc::Examples::Matlab::SetImage<N,bool,bool>(seg, plhs[0]); plhs[1] = mxCreateDoubleScalar((double)energy); plhs[2] = mxCreateDoubleScalar((double)max_iter); plhs[3] = mxCreateDoubleScalar((double)rdpar.m_c1); plhs[4] = mxCreateDoubleScalar((double)rdpar.m_v1); plhs[5] = mxCreateDoubleScalar((double)rdpar.m_c2); plhs[6] = mxCreateDoubleScalar((double)rdpar.m_v2); }
void addSignalDataField(mxArray* mxTrial, const SignalDataBuffer* psdb, unsigned trialIdx, bool useGroupPrefix, unsigned nSamples) { mxArray* mxData; // field name is groupName_signalName char fieldName[MAX_SIGNAL_NAME]; if(useGroupPrefix) snprintf(fieldName, MAX_SIGNAL_NAME, "%s_%s", psdb->pGroupInfo->name, psdb->name); else strncpy(fieldName, psdb->name, MAX_SIGNAL_NAME); const SampleBuffer* ptb = psdb->buffers + trialIdx; mwSize ndims = (mwSize)psdb->nDims; mwSize dims[MAX_SIGNAL_NDIMS+1]; unsigned nBytesData, totalElements; if(nSamples > ptb->nSamples) nSamples = ptb->nSamples; // to store the matlab data type mxClassID cid = convertDataTypeIdToMxClassId(psdb->dataTypeId); unsigned bytesPerElement = getSizeOfDataTypeId(psdb->dataTypeId); if(psdb->dataTypeId == DTID_CHAR && (psdb->pGroupInfo->type == GROUP_TYPE_PARAM || psdb->type == SIGNAL_TYPE_PARAM)) { // string received as part of param group or as param signal, place as string char strBuffer[MAX_SIGNAL_SIZE+1]; if(nSamples == 0) mxData = mxCreateString(""); else { // first copy string into buffer, then zero terminate it unsigned bytesThisSample = ptb->bytesEachSample[0]; if(bytesThisSample > MAX_SIGNAL_SIZE) { bytesThisSample = MAX_SIGNAL_SIZE; logError("Overflow on signal %s", psdb->name); } memcpy(strBuffer, ptb->data, bytesThisSample); strBuffer[bytesThisSample] = '\0'; // now copy it into a matlab string and store in the cell array mxData = mxCreateString(strBuffer); } } else { // determine whether we can concatenate this signal along some axis bool concat = psdb->concatLastDim; // first check whether the user requested it // then check the dimensions of the signals to see if this is possible // concatenation is allowed only if only the last dimension changes size among the samples // i.e. the non-concatenation dimensions must match exactly for(int d = 0; d < psdb->nDims - 1; d++) { if(psdb->dimChangesSize[d]) { concat = false; break; } } if(concat) { // concatenateable variable signal // determine the dimensions of the concatenated signal. totalElements = ptb->nDataBytes / bytesPerElement; unsigned totalElementsPenultimateDims = 1; for(int i = 0; i < (int)ndims - 1; i++) { dims[i] = (mwSize)(psdb->dims[i]); totalElementsPenultimateDims *= dims[i]; } dims[ndims-1] = totalElements / totalElementsPenultimateDims; // convert row vectors to column vectors if(ndims == 2 && dims[0] == 1) { dims[0] = dims[1]; dims[1] = 1; ndims = 1; } nBytesData = totalElements * bytesPerElement; // create and fill a numeric tensor if(psdb->dataTypeId == DTID_LOGICAL) mxData = mxCreateLogicalArray(ndims, dims); else if(psdb->dataTypeId == DTID_CHAR) mxData = mxCreateCharArray(ndims, dims); else mxData = mxCreateNumericArray(ndims, dims, cid, mxREAL); memcpy(mxGetData(mxData), ptb->data, nBytesData); } else { // data is char or samples have different sizes, put each in a cell array mxData = mxCreateCellMatrix(nSamples, 1); if(psdb->dataTypeId == DTID_CHAR) { // special case char array: make 1 x N char array for each string and store these into // a Nsamples x 1 cell array char* dataPtr = (char*)ptb->data; char strBuffer[MAX_SIGNAL_SIZE+1]; for(unsigned iSample = 0; iSample < nSamples; iSample++) { // first copy string into buffer, then zero terminate it unsigned bytesThisSample = ptb->bytesEachSample[iSample]; // TODO add memory overflow check here memcpy(strBuffer, dataPtr, bytesThisSample); strBuffer[bytesThisSample] = '\0'; // now copy it into a matlab string and store in the cell array mxSetCell(mxData, iSample, mxCreateString(strBuffer)); // advance the data pointer dataPtr+=bytesThisSample; } } else { mxArray* mxSampleData; // variable size numeric signal totalElements = 1; // get size along all dimensions but last which is variable for(int i = 0; i < (int)ndims - 1; i++) { dims[i] = (mwSize)(psdb->dims[i]); totalElements *= dims[i]; } // loop over each sample for(unsigned iSample = 0; iSample < nSamples; iSample++) { unsigned bytesThisSample = ptb->bytesEachSample[iSample]; // calculate last dimension by division dims[ndims-1] = bytesThisSample / bytesPerElement / totalElements; nBytesData = totalElements*dims[ndims-1]*bytesPerElement; // create and fill a numeric tensor if(psdb->dataTypeId == DTID_LOGICAL) mxSampleData = mxCreateLogicalArray(ndims, dims); else mxSampleData = mxCreateNumericArray(ndims, dims, cid, mxREAL); memcpy(mxGetData(mxSampleData), ptb->data, nBytesData); // and assign it into the cell mxSetCell(mxData, iSample, mxSampleData); } } } } // add to trial struct unsigned fieldNum = mxAddField(mxTrial, fieldName); mxSetFieldByNumber(mxTrial, 0, fieldNum, mxData); }
EXPORT mxArray* mongo_bson_array_value(struct bson_iterator_* i) { bson_type sub_type, common_type; struct Rcomplex z; bson_iterator sub[MAXDIM+1]; mwSize ndims = 0; mwSize count[MAXDIM+1]; mwSize dim[MAXDIM+1]; mwSize* mdim = dim + 1; mwSize sizes[MAXDIM+1]; mxArray* ret; mwSize depth, j, len, ofs; int isRow = 0; sub[0] = *(bson_iterator*)i; /* count number of dimensions. This is equal to the number of consecutive array markers in the BSON */ do { bson_iterator_subiterator(&sub[ndims], &sub[ndims+1]); if (++ndims > MAXDIM) { mexPrintf("Max dimensions (%d) exceeded. Use an iterator\n", MAXDIM); return 0; } sub_type = bson_iterator_next(&sub[ndims]); } while (sub_type == BSON_ARRAY); /* get the first data value's type */ switch (common_type = sub_type) { case BSON_INT: ; case BSON_LONG: ; case BSON_DOUBLE: ; /* case BSON_STRING: ; */ case BSON_BOOL: ; case BSON_DATE: break; case BSON_OBJECT: if (_iterator_getComplex(&sub[ndims], &z)) break; /* fall thru to default */ default: /* including empty array */ mexPrintf("Unable to convert array - invalid type (%d)", common_type); return 0; } /* initial lowest level count */ for (j = 0; j <= ndims; j++) count[j] = 1; while ((sub_type = bson_iterator_next(&sub[ndims])) != BSON_EOO) { if (sub_type != common_type) { mexPrintf("Unable to convert array - inconsistent types"); return 0; } if (sub_type == BSON_OBJECT && !_iterator_getComplex(&sub[ndims], &z)) { mexPrintf("Unable to convert array - invalid subobject"); return 0; } ++count[ndims]; } /* step through rest of array -- checking common type and dimensions */ memset(dim, 0, sizeof(dim)); depth = ndims; while (depth >= 1) { sub_type = bson_iterator_next(&sub[depth]); switch (sub_type) { case BSON_EOO: if (dim[depth] == 0) dim[depth] = count[depth]; else if (dim[depth] != count[depth]) { mexPrintf("Unable to convert array - inconsistent dimensions"); return 0; } depth--; break; case BSON_ARRAY: count[depth]++; bson_iterator_subiterator(&sub[depth], &sub[depth+1]); if (++depth > ndims) { mexPrintf("Unable to convert array - inconsistent dimensions"); return 0; } count[depth] = 0; break; case BSON_INT: ; case BSON_LONG: ; case BSON_DOUBLE: ; /* case BSON_STRING: ; */ case BSON_BOOL: ; case BSON_DATE: ; GotEl: { if (depth != ndims || sub_type != common_type) { mexPrintf("Unable to convert array - inconsistent dimensions or types"); return 0; } count[depth]++; break; } case BSON_OBJECT: if (_iterator_getComplex(&sub[depth], &z)) goto GotEl; /* fall thru to default */ default: mexPrintf("Unable to convert array - invalid type (%d)", sub_type); return 0; } } if (ndims > 1) { j = dim[ndims]; /* reverse row and column */ dim[ndims] = dim[ndims-1]; dim[ndims-1] = j; } /* calculate offset each dimension multiplies it's index by */ len = 1; for (depth = ndims; depth > 0; depth--) { sizes[depth] = len; len *= dim[depth]; } if (ndims > 1) { reverse(mdim, ndims); /* reverse dimensions for Matlab */ j = sizes[ndims]; sizes[ndims] = sizes[ndims-1]; sizes[ndims-1] = j; } else { isRow = 1; ndims = 2; mdim[1] = mdim[0]; mdim[0] = 1; } /* for (j = 1; j <= ndims; j++) mexPrintf("%d ", dim[j]); mexPrintf("\n"); for (j = 1; j <= ndims; j++) mexPrintf("%d ", sizes[j]); mexPrintf("\n"); */ switch (common_type) { case BSON_INT: ret = mxCreateNumericArray(ndims, mdim, mxINT32_CLASS, mxREAL); break; case BSON_LONG: ret = mxCreateNumericArray(ndims, mdim, mxINT64_CLASS, mxREAL); break; case BSON_DATE: case BSON_DOUBLE: ret = mxCreateNumericArray(ndims, mdim, mxDOUBLE_CLASS, mxREAL); break; /* case BSON_STRING: */ case BSON_BOOL: ret = mxCreateLogicalArray(ndims, mdim); break; case BSON_OBJECT: ret = mxCreateNumericArray(ndims, mdim, mxDOUBLE_CLASS, mxCOMPLEX); break; default: /* never reaches here */ ret = 0; } if (isRow) ndims--; /* step through array(s) again, pulling out values */ bson_iterator_subiterator(&sub[0], &sub[1]); depth = 1; count[depth] = 0; while (depth >= 1) { sub_type = bson_iterator_next(&sub[depth]); count[depth]++; if (sub_type == BSON_EOO) { depth--; } else if (sub_type == BSON_ARRAY) { bson_iterator_subiterator(&sub[depth], &sub[depth+1]); depth++; count[depth] = 0; } else { ofs = 0; for (j = 1; j <= ndims; j++) ofs += sizes[j] * (count[j] - 1); switch (sub_type) { case BSON_INT: ((int*)mxGetData(ret))[ofs] = bson_iterator_int(&sub[depth]); break; case BSON_DATE: mxGetPr(ret)[ofs] = 719529.0 + bson_iterator_date(&sub[depth]) / (1000.0 * 60 * 60 * 24); break; case BSON_DOUBLE: mxGetPr(ret)[ofs] = bson_iterator_double(&sub[depth]); break; case BSON_LONG: ((int64_t*)mxGetData(ret))[ofs] = bson_iterator_long(&sub[depth]); break; case BSON_STRING: break; case BSON_BOOL: ; ((mxLogical*)mxGetData(ret))[ofs] = bson_iterator_bool(&sub[depth]); break; case BSON_OBJECT: _iterator_getComplex(&sub[depth], &z); mxGetPr(ret)[ofs] = z.r; mxGetPi(ret)[ofs] = z.i; break; default: ; /* never reaches here */ } } } return ret; }
void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) { size_t n,j; size_t nCard; bool isLast, lastPassed; mxArray *codeArray; if(nrhs<1){ mexErrMsgTxt("Not enough inputs."); } if(nrhs>2){ mexErrMsgTxt("Too many inputs."); } if(nlhs>4) { mexErrMsgTxt("Too many outputs."); } //If an empty code matrix is passed, then the second argument is //required, and we will return the first gray code in the sequence. if(mxIsEmpty(prhs[0])) { mwSize dims[2]; if(nrhs<2) { mexErrMsgTxt("The second argument is required when an empty code matrix is passed."); } dims[0]=getSizeTFromMatlab(prhs[1]); dims[1]=1; //Allocate the array; this also initializes all of the elements to //0. codeArray=mxCreateLogicalArray(2, dims); //This is the code plhs[0]=codeArray; if(nlhs>1) { //This is nCard plhs[1]=mxCreateDoubleScalar(0.0); if(nlhs>2) { //This is isLast plhs[2]=mxCreateLogicalScalar(false); if(nlhs>3) { //This is j. plhs[3]=mxCreateDoubleMatrix(0, 0, mxREAL); } } } return; } //The code array cannot be complex. if(mxIsComplex(prhs[0])!=false) { mexErrMsgTxt("The code array cannot be complex."); } //Copy the code value so that the input matrix is not modified on //return. { size_t n1,n2; n1=mxGetM(prhs[0]); n2=mxGetN(prhs[0]); if((n1==1&&n2>=1)||(n2==1&&n1>=1)) { n=std::max(n1,n2); codeArray=mxDuplicateArray(prhs[0]); } else { mexErrMsgTxt("The code vector has the wrong dimensionality."); } } if(nrhs>1) { nCard=getSizeTFromMatlab(prhs[1]); } else { mxArray *lhs[1]; //Sum up the ones in codeArray to get nCard if it is not provided. mexCallMATLAB(1,lhs,1, &codeArray, "sum"); nCard=getSizeTFromMatlab(lhs[0]); mxDestroyArray(lhs[0]); } //The type of the data in the code array is whatever the user passed to //the function. The function has to be called with the correct template //value for the type of the code. lastPassed=false; switch(mxGetClassID(codeArray)){ case mxCHAR_CLASS: { mxChar *code=(mxChar*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxLOGICAL_CLASS: { mxLogical* code=(mxLogical*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxDOUBLE_CLASS: { double* code=(double*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxSINGLE_CLASS: { float* code=(float*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxINT8_CLASS: { int8_T* code=(int8_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxUINT8_CLASS: { uint8_T* code=(uint8_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxINT16_CLASS: { int16_T* code=(int16_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxUINT16_CLASS: { uint16_T* code=(uint16_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxINT32_CLASS: { int32_T* code=(int32_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxUINT32_CLASS: { uint32_T* code=(uint32_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxINT64_CLASS: { int64_T* code=(int64_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxUINT64_CLASS: { uint64_T* code=(uint64_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } default: mexErrMsgTxt("The code vector is of an unknown data type."); } //If the final gray code was passed, then just return empty matrices //and put n in nCard. That way, if called again, the function will //start from the beginning. if(lastPassed==true) { mxDestroyArray(codeArray); plhs[0]=mxCreateDoubleMatrix(0, 0, mxREAL); if(nlhs>1) { mxArray *nCardMat=allocUnsignedSizeMatInMatlab(1, 1); *(size_t*)mxGetData(nCardMat)=n; plhs[1]=nCardMat; if(nlhs>2) { //This is isLast plhs[2]=mxCreateDoubleMatrix(0, 0, mxREAL);; if(nlhs>3) { //This is j plhs[3]=mxCreateDoubleMatrix(0, 0, mxREAL);; } } } return; } //Set the return values for the case when the last code was not passed. plhs[0]=codeArray; if(nlhs>1) { mxArray *nCardMat=allocUnsignedSizeMatInMatlab(1, 1); *(size_t*)mxGetData(nCardMat)=nCard; plhs[1]=nCardMat; if(nlhs>2) { //This is isLast plhs[2]=mxCreateLogicalScalar(isLast); if(nlhs>3) { mxArray *jMat=allocUnsignedSizeMatInMatlab(1, 1); //Increment j to be an index for Matlab. j++; *(size_t*)mxGetData(jMat)=j; plhs[3]=jMat; } } } }
void mexFunction(int nlhs, mxArray* plhs[], const int nrhs, const mxArray* prhs[]) { if (nrhs != 3) { mexPrintf("Exactly 3 arguments required."); } // Grab the region mask (HxW). int H = mxGetM(prhs[ARG_IMG_REGIONS]); int W = mxGetN(prhs[ARG_IMG_REGIONS]); int N = H * W; if (mxGetClassID(prhs[ARG_IMG_REGIONS]) != mxINT32_CLASS) { mexErrMsgTxt("imgRegions must be of class 'int32'"); } int* img_regions = (int*) mxGetData(prhs[ARG_IMG_REGIONS]); // Get the number of regions. int R = (int) mxGetScalar(prhs[ARG_NUM_REGIONS]); // Grab the eroded region mask. if (mxGetNumberOfDimensions(prhs[ARG_IMG_ERODED]) != 2 || mxGetNumberOfElements(prhs[ARG_IMG_ERODED]) != N) { mexErrMsgTxt("imgEroded must be of size HxW"); } else if (mxGetClassID(prhs[ARG_IMG_ERODED]) != mxLOGICAL_CLASS) { mexErrMsgTxt("imgEroded must be of class 'logical'"); } bool* img_eroded = (bool*) mxGetData(prhs[ARG_IMG_ERODED]); // Create the outputs. mwSize ndims_out = 3; mwSize dims_out[] = {H, W, R}; plhs[RET_INTERIORS] = mxCreateLogicalArray(ndims_out, &dims_out[0]); plhs[RET_EDGES] = mxCreateLogicalArray(ndims_out, &dims_out[0]); mwSize ndims_out_size = 2; mwSize dims_out_size[] = {R, 1}; bool* img_interiors = (bool*) mxGetData(plhs[RET_INTERIORS]); bool* img_edges = (bool*) mxGetData(plhs[RET_EDGES]); // unsigned int num_pix_interiors[R]; // unsigned int num_pix_edges[R]; unsigned int * num_pix_interiors = new unsigned int [R]; unsigned int * num_pix_edges = new unsigned int [R]; for (int rr = 0; rr < R; ++rr) { num_pix_interiors[rr] = 0; num_pix_edges[rr] = 0; } for (int ii = 0; ii < N; ++ii, ++img_eroded) { // Grab the Region ID. int region_id = img_regions[ii] - 1; // Is it in the interior? if (*img_eroded) { img_interiors[region_id * N + ii] = true; ++num_pix_interiors[region_id]; } else { img_edges[region_id * N + ii] = true; ++num_pix_edges[region_id]; } } // Now that we know how many pixels make up the interiors and borders, // if we have any interiors or border regions that are empty, just use // the entire mask instead. for (int ii = 0; ii < N; ++ii) { // Grab the Region ID. int region_id = img_regions[ii] - 1; if (num_pix_interiors[region_id] == 0) { img_interiors[region_id * N + ii] = true; } if (num_pix_edges[region_id] == 0) { img_edges[region_id * N + ii] = true; } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { struct mxArray_Tag *mx; mwSize inbytes, outbytes, i, k, idim, ndim; mwSize *dims_old, *dims_new; char *outstring; mxClassID outclass; int out_numeric; /* Check input arguments */ if( nrhs > 2 ) { mexErrMsgTxt("Too many input arguments."); } if( nrhs < 2 ) { mexErrMsgTxt("Not enough input arguments."); } if( nlhs > 1 ) { mexErrMsgTxt("Too many output arguments."); } if( mxIsSparse(prhs[0]) || (!mxIsNumeric(prhs[0]) && !mxIsChar(prhs[0]) && !mxIsLogical(prhs[0])) ) { mexErrMsgTxt("The first input argument must be a full numeric value, or char, or logical."); } if( !mxIsChar(prhs[1]) ) { mexErrMsgTxt("The second input argument must be a character array."); } /* Get input argument byte length */ inbytes = mxGetElementSize(prhs[0]); /* Check second input argument for desired output type */ outstring = mxArrayToString(prhs[1]); out_numeric = 1; if( strcmp(outstring,"int8") == 0 ) { outclass = mxINT8_CLASS; outbytes = 1; } else if( strcmp(outstring,"uint8") == 0 ) { outclass = mxUINT8_CLASS; outbytes = 1; } else if( strcmp(outstring,"int16") == 0 ) { outclass = mxINT16_CLASS; outbytes = 2; } else if( strcmp(outstring,"uint16") == 0 ) { outclass = mxUINT16_CLASS; outbytes = 2; } else if( strcmp(outstring,"int32") == 0 ) { outclass = mxINT32_CLASS; outbytes = 4; } else if( strcmp(outstring,"uint32") == 0 ) { outclass = mxUINT32_CLASS; outbytes = 4; } else if( strcmp(outstring,"int64") == 0 ) { outclass = mxINT64_CLASS; outbytes = 8; } else if( strcmp(outstring,"uint64") == 0 ) { outclass = mxUINT64_CLASS; outbytes = 8; } else if( strcmp(outstring,"double") == 0 ) { outclass = mxDOUBLE_CLASS; outbytes = 8; } else if( strcmp(outstring,"single") == 0 ) { outclass = mxSINGLE_CLASS; outbytes = 4; } else if( strcmp(outstring,"char") == 0 ) { outclass = mxCHAR_CLASS; outbytes = 2; out_numeric = 0; } else if( strcmp(outstring,"logical") == 0 ) { outclass = mxLOGICAL_CLASS; outbytes = 1; out_numeric = 0; } else { mxFree(outstring); mexErrMsgTxt("Unsupported class.\n"); } mxFree(outstring); /* Check for complex coversion to non-numeric */ if( mxIsComplex(prhs[0]) && !out_numeric ) { mexErrMsgTxt("Cannot typecast a complex input to a non-numeric class.\n"); } /* Check for empty input. No data to share, so simply create a new empty variable */ if( mxIsEmpty(prhs[0]) ) { if( out_numeric ) { plhs[0] = mxCreateNumericArray(mxGetNumberOfDimensions(prhs[0]), mxGetDimensions(prhs[0]), outclass, mxREAL); } else if( outclass == mxCHAR_CLASS ) { plhs[0] = mxCreateCharArray(mxGetNumberOfDimensions(prhs[0]), mxGetDimensions(prhs[0])); } else { plhs[0] = mxCreateLogicalArray(mxGetNumberOfDimensions(prhs[0]), mxGetDimensions(prhs[0])); } return; } /* Check the old & new sizes for compatibility */ ndim = mxGetNumberOfDimensions(prhs[0]); dims_old = mxGetDimensions(prhs[0]); for( i=0; i<ndim; i++ ) { if( dims_old[i] != 1 || i == ndim-1 ) { k = (dims_old[i] * inbytes) / outbytes; if( k * outbytes != dims_old[i] * inbytes ) { mexErrMsgTxt("Too few input values to make output type.\n"); } idim = i; break; } } dims_new = mxMalloc(ndim * sizeof(*dims_new)); for( i=0; i<ndim; i++ ) { dims_new[i] = dims_old[i]; } dims_new[idim] = k; /* Create the output array as a shared data copy, then manually set the class * and size parameters by accessing the structure fields directly. Note that * this is using undocumented MATLAB API functions and hacking of the * mxArray_tag structure, so this may not work in future versions of MATLAB. */ // mx = (struct mxArray_Tag *) prhs[0]; // printf("old flags: %#6x\n", mx->flags); plhs[0] = mxCreateSharedDataCopy(prhs[0]); mx = (struct mxArray_Tag *) plhs[0]; mx->ClassID = outclass; mx->VariableType = VariableType_Temporary; mxSetDimensions(plhs[0],dims_new,ndim); mxFree(dims_new); //mexPrintf("post shared data copy\n"); // printf("new flags: %#6x\n", mx->flags); return; // this breaks in R2018a, @djoshea removing /* Also need to fix up the flags */ if( outclass == mxDOUBLE_CLASS ) { if( mxGetNumberOfElements(plhs[0]) == 1 ) { mx->flags = 0x0211; /* Set numeric, temporary, and full double scalar bits */ } else { mx->flags = 0x0210; /* Set numeric and temporary bits */ } } else if( out_numeric ) { mx->flags = 0x0210; /* Set numeric and temporary bits */ } else { mx->flags = 0x0010; /* Set the temporary bit */ } }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ int n, i, j ,k, I, J, K, IJ, I1, J1, K1; int i0,i1,j0,j1,k0,k1,slice; mwSize sizes[3]; mxLogical *V, *O; int connect; if( nrhs < 1 ){ mxErrMsgTxt("sintax error\n"); } if( !mxIsLogical( prhs[0] ) ){ mxErrMsgTxt("array have to be logical.\n"); } if( myNDims( prhs[0] ) > 3 ){ mxErrMsgTxt("bigger than 3d arrays is not allowed.\n"); } if( nrhs > 1 ){ connect = myGetValue( prhs[1] ); if( connect != 26 && connect != 18 && connect != 6 ){ mxErrMsgTxt("valid connects are 6, 18, 26.\n"); } } else { connect = 26; } I = mySize( prhs[0] , 0 ); J = mySize( prhs[0] , 1 ); K = mySize( prhs[0] , 2 ); IJ = I*J; I1 = I-1; J1 = J-1; K1 = K-1; sizes[0] = I; sizes[1] = J; sizes[2] = K; V = (mxLogical *) mxGetData( prhs[0] ); plhs[0] = mxCreateLogicalArray( 3 , sizes ); O = (mxLogical *) mxGetData( plhs[0] ); if( connect == 26 ){ n = 0; for( k = 0 ; k < K ; k++ ){ k0 = k > 0 ? k - 1 : k; k1 = k < K1 ? k + 1 : k; for( j = 0 ; j < J ; j++ ){ j0 = j > 0 ? j - 1 : j; j1 = j < J1 ? j + 1 : j; for( i = 0 ; i < I ; i++ ){ if( V[n] ){ i0 = i > 0 ? i - 1 : i; i1 = i < I1 ? i + 1 : i; O( i0 , j0 , k0 ) = 1; O( i , j0 , k0 ) = 1; O( i1 , j0 , k0 ) = 1; O( i0 , j , k0 ) = 1; O( i , j , k0 ) = 1; O( i1 , j , k0 ) = 1; O( i0 , j1 , k0 ) = 1; O( i , j1 , k0 ) = 1; O( i1 , j1 , k0 ) = 1; O( i0 , j0 , k ) = 1; O( i , j0 , k ) = 1; O( i1 , j0 , k ) = 1; O( i0 , j , k ) = 1; O[ n ] = 1; O( i1 , j , k ) = 1; O( i0 , j1 , k ) = 1; O( i , j1 , k ) = 1; O( i1 , j1 , k ) = 1; O( i0 , j0 , k1 ) = 1; O( i , j0 , k1 ) = 1; O( i1 , j0 , k1 ) = 1; O( i0 , j , k1 ) = 1; O( i , j , k1 ) = 1; O( i1 , j , k1 ) = 1; O( i0 , j1 , k1 ) = 1; O( i , j1 , k1 ) = 1; O( i1 , j1 , k1 ) = 1; } n++; } } } } else if( connect == 18 ){ n = 0; for( k = 0 ; k < K ; k++ ){ k0 = k > 0 ? k - 1 : k; k1 = k < K1 ? k + 1 : k; for( j = 0 ; j < J ; j++ ){ j0 = j > 0 ? j - 1 : j; j1 = j < J1 ? j + 1 : j; for( i = 0 ; i < I ; i++ ){ if( V[n] ){ i0 = i > 0 ? i - 1 : i; i1 = i < I1 ? i + 1 : i; O( i , j0 , k0 ) = 1; O( i0 , j , k0 ) = 1; O( i , j , k0 ) = 1; O( i1 , j , k0 ) = 1; O( i , j1 , k0 ) = 1; O( i0 , j0 , k ) = 1; O( i , j0 , k ) = 1; O( i1 , j0 , k ) = 1; O( i0 , j , k ) = 1; O[ n ] = 1; O( i1 , j , k ) = 1; O( i0 , j1 , k ) = 1; O( i , j1 , k ) = 1; O( i1 , j1 , k ) = 1; O( i , j0 , k1 ) = 1; O( i0 , j , k1 ) = 1; O( i , j , k1 ) = 1; O( i1 , j , k1 ) = 1; O( i , j1 , k1 ) = 1; } n++; } } } } else if( connect == 6 ){ n = 0; for( k = 0 ; k < K ; k++ ){ k0 = k > 0 ? k - 1 : k; k1 = k < K-1 ? k + 1 : k; for( j = 0 ; j < J ; j++ ){ j0 = j > 0 ? j - 1 : j; j1 = j < J-1 ? j + 1 : j; for( i = 0 ; i < I ; i++ ){ if( V[n] ){ i0 = i > 0 ? i - 1 : i; i1 = i < I-1 ? i + 1 : i; O( i0 , j , k ) = 1; O( i , j , k ) = 1; O( i1 , j , k ) = 1; O( i , j0 , k ) = 1; O[ n ] = 1; O( i , j1 , k ) = 1; O( i , j , k0 ) = 1; O( i , j , k ) = 1; O( i , j , k1 ) = 1; } n++; } } } } }