1

我正在尝试使用我的渲染脚本找到我的相机图像的最小和最大像素值。我的渲染脚本文件尝试调用 rsSetElementAt 但我收到以下警告:

C:\Users\tec\workspace\RSTestProject\src\com\myrs.rs:59:9:警告:函数 'rsSetElementAt_uint' 的隐式声明在 C99 中无效

因为这是一个警告,所以我继续运行 rs。该程序因以下错误而崩溃:

E/RenderScript: rsSetElementAt_uint 的 ScriptC 符号查找失败

这是怎么回事?谢谢

#pragma version(1)
#pragma rs java_package_name(com.techleadz.rstestproject)

rs_allocation gIn;
rs_allocation gOut;
rs_allocation gMin; // min matrix
rs_allocation gMax; // max matrix
bool reduce_constraints;
bool reset_constraints;
rs_script gScript;
//const uchar4 *gPixels;
int mode;

// this is invoked automatically
void init() {
    rsDebug( "initRS:", "mode" );
}

void filter() {
    rsDebug( "Number of Rows:", "mode" );
    rsForEach( gScript, gIn, gOut );
}

void RegisterPixels( const uchar4 *v_in, uchar4 *v_out, uint32_t column, uint32_t row ) {

    unsigned int input = (int)v_in;
    rsDebug( "Number of Rows:", rsAllocationGetDimX(gIn) );

    rsDebug("Printing out a Point", input);
    // see if this pixel exceeds the min and max

    // get an entire row if possible ????
    const uint *minRow = rsGetElementAt( gMin, row, column );
    const uint *maxRow = rsGetElementAt( gMax, row, column );

    uint newMinRow, newMaxRow;
    unsigned char minRowRed, minRowGreen, minRowBlue;
    unsigned char maxRowRed, maxRowGreen, maxRowBlue;

    minRowRed   = *minRow&0xff;
    minRowGreen = *minRow&0xff00 >> 8;
    minRowBlue  = *minRow&0xff0000 >> 16;
    maxRowRed   = *maxRow&0xff;
    maxRowGreen = *maxRow&0xff00 >> 8;
    maxRowBlue  = *maxRow&0xff0000 >> 16;

    // if reduce_constraints then do it first. This will force the constraints
    if( mode == 1 ) // gReduce_constraints == true ) {
    {
        // to recalculate as the sun rises or sets

        // go through the entire row
        minRowRed += 1; minRowGreen += 1; minRowBlue += 1;
        maxRowRed -= 1; maxRowGreen -= 1; maxRowBlue -= 1;

        // recombined RGB
        newMinRow = minRowRed & (minRowGreen<<8) & (minRowBlue<<16);
        newMaxRow = maxRowRed & (maxRowGreen<<8) & (maxRowBlue<<16);
        rsSetElementAt_uint( gMin, newMinRow, row, column );
        //rsSetElementAt_int( gMin, 0, 0 );
        //rsSetElementAt_uint( gMax, newMaxRow, row, column );
    }
    unsigned char inputRed = input&0xff;
    unsigned char inputGreen = (input&0xff00)>>8;
    unsigned char inputBlue = (input&0xff0000)>>16;
    // first see if this pixel is the wrong color
    // Brown deer are within a range of RGB values
    if( ( inputRed < 40 ) && ( inputRed > 218 ) ) return;
    if( ( inputGreen < 40 ) && ( inputGreen > 177 ) ) return;
    if( ( inputBlue < 40 ) && ( inputBlue > 167 ) ) return;

    if( ( inputRed > minRowRed ) && ( inputRed < maxRowRed ) ) {
        if( ( inputGreen > minRowGreen ) && ( inputGreen < maxRowGreen ) ) {
            if( ( inputBlue > minRowBlue ) && ( inputBlue < maxRowBlue ) ) {
                newMaxRow = newMaxRow | 0xff000000;
                v_out = newMaxRow;
                // place the hit in the upper byte
                //rsSetElementAt_int( gMax, newMaxRow, row, column );
            }
        }
    }

    return;
}

// the following RenderScript will find the min and max pixel
//void __attribute__((kernel))LearnArea( uint row ) {
void LearnArea( const uchar4 *v_in, uchar4 *v_out, uint32_t column, uint32_t row) {
    const unsigned int *lmin;
    const unsigned int *lmax;
    unsigned int newlmin;
    unsigned int newlmax;
    bool changed = false;
    rsDebug( "LearnArea:", rsAllocationGetDimX(gIn) );
    unsigned int input = (int)v_in;
    unsigned char inputRed   = input&0xff;
    unsigned char inputGreen = (input&0xff00)>>8;
    unsigned char inputBlue  = (input&0xff0000)>>16;

    if( reset_constraints == true) {
        rsSetElementAt_int( gMin, 255, row, column );
        //rsSetElementAt_int( gMax, 0, row, column );
    }
    else {
        lmin = rsGetElementAt( gMin, row, column );
        lmax = rsGetElementAt( gMax, row, column );

        unsigned char minRed   = *lmin&0xff;
        unsigned char minGreen = (*lmin&0xff00)>>8;
        unsigned char minBlue  = (*lmin&0xff0000)>>16;

        // see if the current pixel is less than the min
        changed = false;
        if( inputRed < minRed ) {
            minRed = inputRed;// red
            changed = true;
        }
        if( inputGreen < minGreen ) {
            minGreen = inputGreen; // green
            changed = true;
        }
        if( inputBlue < minBlue ) {
            minBlue = inputBlue;// blue
            changed = true;
        }

        if( changed == true ) {
            newlmin = minRed & (minGreen<<8) & (minBlue<<16);
            rsSetElementAt_int( gMin, newlmin, row, column );
        }

        unsigned char maxRed   = *lmax&0xff;
        unsigned char maxGreen = (*lmax&0xff00)>>8;
        unsigned char maxBlue  = (*lmax&0xff0000)>>16;

        changed = false;
        // see if the current pixel is less than the min
        if( inputRed < maxRed ) {
            maxRed = inputRed;// red
            changed = true;
        }
        if( inputGreen < maxGreen ) {
            maxGreen = inputGreen;// green
            changed = true;
        }
        if( inputBlue < maxBlue ) {
            maxBlue = inputBlue;// blue
            changed = true;
        }
        if( changed == true ) {
            newlmax = maxRed & (maxGreen<<8) & (maxBlue<<16);
            v_out =
            rsSetElementAt_int( gMax, newlmax, row, column );
        }
    }
    return;
}

/*
// use a radius to decide if a large area has exceed the thresholds
//void __attribute__((kernel))FindHits( uint rowCenter, uint cellSize, uint threshold )
void FindHits( uint rowCenter, uint cellSize, uint threshold )
{
    uint columnSum=0; // sum of the current sub column
    uint sums[cellSize]; // sum of a small column
    uint runningSum=0; // the sum of the cells_size x cell_size
    uint halfCellSize = cellSize/2;
    uint currentColumn=0;
    rsDebug( "FindHits:", rsAllocationGetDimX(gIn) ); // rsUptimeMillis()

    uint rowOffset = rowCenter - halfCellSize; // shortcut from doing this every iteration

    for( uint i=0; i < gWidth; i ++ ) {
        columnSum = 0;
        for( uint j=0; j < cellSize; j ++ ) {
            columnSum += rsElementGet_int( gHits, rowOffset + j, i );
        }
        if( i < cellSize ) {
            runningSum += columnSum;
        }
        else {
            // always subtract off the trailing column and add the current column
            runningSum = runningSum + columnSum - sums[currentColumn];
            if( runningSum > threshold ) {
                gMovementPresentRow = rowCenter;
                gMovementPresentColumn = i;
                return;
            }
            sums[currentColumn] = columnSum;
        }
        currentColumn ++;
        if( currentColumn > cellSize ) currentColumn = 0;
    }
    return;
}
*/

void root( const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y ) // v_out is the min/max
{
    rsDebug( "root:", "mode is" );
    if( mode == 0 )
    {
        RegisterPixels( v_in, v_out, x, y );
        rsDebug( "root:", "mode is 0" );
    }
    else if( mode == 1 )
    {
        //LeanArea( v_in, v_out );
        rsDebug( "root:", "mode is 1" );
    }
    else if( mode == 2 )
    {
        rsDebug( "root:", "mode is 2" );
        //FindHits( v_in, v_out );
    }
    else
        rsDebug( "root:", "mode is 3" );
4

2 回答 2

3

rsSetElementAt() 和 rsSetElementAt_*() 仅从目标 API 18 开始可用。由于 API 18 尚未在任何 Android 设备上实际可用,因此在下一个 Android 版本发布之前,您将无法正确执行此代码. 我不确定你是如何设法让函数实际声明得足以编译(也许这是使用最新的 SDK?),但它现在总是无法加载到设备上。

于 2013-07-03T07:31:02.363 回答
2

问题出在 renderScriptTargetApi 上。为了使用 rsSetElementAt,请将您的 renderScriptTargetApi 保持为 18。此外,如果问题仍然存在,请检查 rsSetElementAt 所需的所有参数是否具有文档中提供的确切数据类型。在您的情况下,将行和列类型转换为 rsSetElementAt_int( gMax, newlmax, (uint32_t)row, (uint32_t)column );

于 2016-01-20T07:43:22.773 回答