本帖最后由 limeng_77 于 2011-05-15 22:46:57 编辑

解决方案 »

  1.   

    给lz一个双线性插值参考:
    http://www.cvchina.info/2011/04/19/bilinear-interpolation/
      

  2.   

    双线性插值,跟opencv没关系,主要是要理解它的原理,然后,就好做了,个人觉得,很容易实现的。
      

  3.   

    链接可以打开的啊:static void _ieInterpImageBilinear8UC1_Ver3_RowFilter(unsigned char* src, long* dst, int len, int* leftIdx, int* rightIdx, long* weight, int shift)
    {
        int i;
        for(i = 0; i < len - 4; i+=4){
            *dst++ = ((1<<shift) - weight[i])*src[leftIdx[i]] + weight[i]*src[rightIdx[i]];
            *dst++ = ((1<<shift) - weight[i+1])*src[leftIdx[i+1]] + weight[i+1]*src[rightIdx[i+1]];
            *dst++ = ((1<<shift) - weight[i+2])*src[leftIdx[i+2]] + weight[i+2]*src[rightIdx[i+2]];
            *dst++ = ((1<<shift) - weight[i+3])*src[leftIdx[i+3]] + weight[i+3]*src[rightIdx[i+3]];
     
        }
        for( ; i < len; ++i){
            *dst++ = ((1<<shift) - weight[i])*src[leftIdx[i]] + weight[i]*src[rightIdx[i]];
        }
    }
     
    static void _ieInterpImageBilinear8UC1_Ver3(Image* src, Image* dst)
    {
        int i, j;
        int sw, sh, sstep;
        int dw, dh, dstep;
        unsigned char *sdata, *ddata;
        float horScaleRatio, verScaleRatio;
        long *rowBuf1, *rowBuf2;
        long *upLinePtr, *downLinePtr, *tempPtr;
        long *horWeight;
        int *horLeftIdx, *horRightIdx;
        int preVerUpIdx, preVerDownIdx;
        int shift = 8;
     
        sw = src->w; sh = src->h; sstep = src->step; sdata = (unsigned char*)(src->data);
        dw = dst->w; dh = dst->h; dstep = dst->step; ddata = (unsigned char*)(dst->data);
     
        horScaleRatio = sw / (float)(dw);
        verScaleRatio = sh / (float)(dh);
     
        rowBuf1 = new long[dw];
        rowBuf2 = new long[dw];
        horWeight = new long[dw];
        horLeftIdx = new int[dw];
        horRightIdx = new int[dw];
     
        
    //col interpolation
        
    //计算目标图像像素横向的左右邻居序号,和权重。
        for(i = 0; i < dw; i++){
            float pos = (i + 0.5f) * horScaleRatio;
            horLeftIdx[i] = (int)(IET_MAX(pos - 0.5f, 0));
            horRightIdx[i] = (int)(IET_MIN(pos + 0.5f, sw-1));
            horWeight[i] = (long) (fabs(pos - 0.5f - horLeftIdx[i]) * (1<<shift));
        }
     
        preVerUpIdx = -1;
        preVerDownIdx = -1;
        upLinePtr = rowBuf1;
        downLinePtr = rowBuf2;
        for(j = 0; j < dh; j++){
            float pos = (j + 0.5f) * verScaleRatio;
            int verUpIdx = (int)(IET_MAX(pos - 0.5f, 0));
            int verDownIdx = (int)(IET_MIN(pos + 0.5f, sh-1));
            long verWeight = (long) (fabs(pos - 0.5f - verUpIdx) * (1<<shift));
     
            if(verUpIdx == preVerUpIdx && verDownIdx == preVerDownIdx){
                ;
    //do nothing
            }
            else if(verUpIdx == preVerDownIdx){
                IET_SWAP(upLinePtr, downLinePtr, tempPtr);
                _ieInterpImageBilinear8UC1_Ver3_RowFilter(sdata + sstep*verDownIdx, downLinePtr, dw, horLeftIdx, horRightIdx, horWeight, shift);
            }else{
                _ieInterpImageBilinear8UC1_Ver3_RowFilter(sdata + sstep*verUpIdx,   upLinePtr, dw, horLeftIdx, horRightIdx, horWeight, shift);
                _ieInterpImageBilinear8UC1_Ver3_RowFilter(sdata + sstep*verDownIdx, downLinePtr, dw, horLeftIdx, horRightIdx, horWeight, shift);
            }        
     
            unsigned char* _ptr = ddata + dstep*j;
            for(i = 0; i < dw-4; i+=4){
                *_ptr++ = (unsigned char) ( (((1<<shift) - verWeight)*upLinePtr[i] + verWeight*downLinePtr[i]) >> (2*shift) );
                *_ptr++ = (unsigned char) ( (((1<<shift) - verWeight)*upLinePtr[i+1] + verWeight*downLinePtr[i+1]) >> (2*shift) );
                *_ptr++ = (unsigned char) ( (((1<<shift) - verWeight)*upLinePtr[i+2] + verWeight*downLinePtr[i+2]) >> (2*shift) );
                *_ptr++ = (unsigned char) ( (((1<<shift) - verWeight)*upLinePtr[i+3] + verWeight*downLinePtr[i+3]) >> (2*shift) );
            }
            for(; i < dw; i++){
                *_ptr++ = (unsigned char) ( (((1<<shift) - verWeight)*upLinePtr[i] + verWeight*downLinePtr[i]) >> (2*shift) );
            }
            preVerUpIdx = verUpIdx;
            preVerDownIdx = verDownIdx;
        }
        delete []rowBuf1;
        delete []rowBuf2;
        delete []horWeight;
        delete []horLeftIdx;
        delete []horRightIdx;
    }