Пример #1
0
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);
}
Пример #2
0
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
    }
}
Пример #3
0
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.
    }
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
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;
    }
  }
}
Пример #9
0
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 */
   }
}
Пример #10
0
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++;
        }
      }
    }

  }

  
}