烦死了,关于获取图像数据的二维数组操作,谁能解决偶一定高分相送!

时间:2022-07-07 21:26:50
在VB中,偶可以很简单的使用如下的代码来实现对于一幅图像的图像数据获取,例如下面的代码:

       Dim dl              As Long
       Dim bmpinfo  As BITMAPINFO
       Dim pixel1()  As Byte
       Dim r As Long
       
'建立位图信息结构(用于GetDIBits和SetDIBits)
With bmpinfo
    .biBitCount = 24
    .biHeight = nHeight
    .biPlanes = 1
    .biSize = 40
    .biWidth = nWidth
    .biSizeImage = ((nWidth * 3 + 3) And &H7FFFFFFC) * nHeight
End With

      Dim SrcBitMap As Long
      SrcBitMap = GetCurrentObject(hSrcDC, OBJ_BITMAP) '取得位图
      If SrcBitMap = 0 Then Exit Sub

      ReDim pixel1(1 To ((nWidth * 3 + 3) And &H7FFFFFFC),1 to nHeight)

      GetDIBits hSrcDC, SrcBitMap, 0, nHeight, pixel1(1,1), bmpinfo, 0       fooAdjustBrightness pixel1(1,1), iValue, nWidth, nHeight, ((nWidth * 3 + 3) And &H7FFFFFFC) * nHeight

      SetDIBits hSrcDC, SrcBitMap, 0, nHeight, pixel1(1,1), bmpinfo, 0 




其中这个pixel1()的数组无论是一维还是二维都可以,这样就方便了我对图形数据的直接操作(无论是逐点修改还是做一个滤波器处理都没问题),但是这种思路换到VC中好像就不行了??

偶在MSDN上搜索了微软的一些例子,可是看到的都是使用类似如下的调用:

GetDIBits(hDC, _hBmp, (UINT)0, (UINT)_bmpInfo.bmiHeader.biHeight, (LPVOID)_buf, &_bmpInfo, DIB_RGB_COLORS);

其中_buf内就是图像数据的首地址。但是这样获取得数据对于使用卷积操作(哪怕只是3x3矩阵的操作)也是痛苦的很,因为需要在1维数组上不停的计算2维数组的对应位置。太容易出错了。所以部知道各位有没有好的办法来解决一下?或者说你们在使用卷积操作时究竟是怎样对数据进行处理的呢?


15 个解决方案

#1


#2


定义一个二维指针,然后将_buf按一定的长度将地址赋予buf指针数组
BYTE** buf;
buf = (BYTE**)(new BYTE[nWidth*nHeight]);
buf[0] = _buf;
buf[1] = _buf + 1 * nWidth;
...
buf[nHeight - 1] = _buf + (nHeight - 1) * nWidth;

这样就可以直接用buf二维数组了

#3


谢谢 Angus83(鱼)

顺便再请教一下其他的图像高手,一般都是怎么做这种程序呢?

#4


我们习惯用一维数组,也不麻烦。

#5


晕。。那么计算卷积呢?比如说5x5的卷积,中间的坐标换算岂不是很难写?

#6


混分

#7


ding

#8


用一维数组表达二维数组,就两行表达式,但一维数组有着高效的内存访问。

#9


unsigned char **pucImageData=NULL;
    pucImageData = new unsigned char *[lWidth];
    for ( i = 0; i < lWidth; i++)
    {
        pucImageData[i] = new unsigned char [lHeight];
    }

for(j=0;j<lHeight;j++)
for(i=0;i<lWidth;i++)
{
pucImageData[i][j]=*(lpDIBBits + lLineBytes * (lHeight - 1 - j) + i);

}



for ( i =0; i<lHeight ; i++)
{
delete pucImageData[i];
}

delete pucImageData;

#10


用1维表示2维, 什么简单, 一般不会出错, 主要你还不习惯. 比如用一维数组表示一个M行N列的二维数组, 可以如下定义 
   BYTE buffer[M*N] ;
  // 要引用第i行j列的数组元素, 就如下
   ... = buffer[ i * N + j ] ...
 

#11


如果你实在不愿意写i*N+j, 那么可以用宏, 比如
#define buffer(i,j)  buffer[(i)*N+(j)]
这样的写法已经跟VB的一样了吧.

#12


看来大家基本都还是用一维数组啊,稍微简便点可以把每行首地址先算出来存起来再调用
d = (int)((1.0-q) * ((1.0-p) * (*(data+((m+ys)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys)*m_nWidth+n+1+xs)*3)))+q * ((1.0-p) * (*(data+ ((m+ys+1)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys+1)*m_nWidth+n+1+xs)*3))));
这是双线性插值的一段,是不是很傻?

#13


关注

#14


一维数组只要控制好长度和宽度甚至高度值就可以很好的实现

#15


你可以把一维数组转换成2维得啊。。。。
同时,一维得算法也可以实现,,,同上。

#1


#2


定义一个二维指针,然后将_buf按一定的长度将地址赋予buf指针数组
BYTE** buf;
buf = (BYTE**)(new BYTE[nWidth*nHeight]);
buf[0] = _buf;
buf[1] = _buf + 1 * nWidth;
...
buf[nHeight - 1] = _buf + (nHeight - 1) * nWidth;

这样就可以直接用buf二维数组了

#3


谢谢 Angus83(鱼)

顺便再请教一下其他的图像高手,一般都是怎么做这种程序呢?

#4


我们习惯用一维数组,也不麻烦。

#5


晕。。那么计算卷积呢?比如说5x5的卷积,中间的坐标换算岂不是很难写?

#6


混分

#7


ding

#8


用一维数组表达二维数组,就两行表达式,但一维数组有着高效的内存访问。

#9


unsigned char **pucImageData=NULL;
    pucImageData = new unsigned char *[lWidth];
    for ( i = 0; i < lWidth; i++)
    {
        pucImageData[i] = new unsigned char [lHeight];
    }

for(j=0;j<lHeight;j++)
for(i=0;i<lWidth;i++)
{
pucImageData[i][j]=*(lpDIBBits + lLineBytes * (lHeight - 1 - j) + i);

}



for ( i =0; i<lHeight ; i++)
{
delete pucImageData[i];
}

delete pucImageData;

#10


用1维表示2维, 什么简单, 一般不会出错, 主要你还不习惯. 比如用一维数组表示一个M行N列的二维数组, 可以如下定义 
   BYTE buffer[M*N] ;
  // 要引用第i行j列的数组元素, 就如下
   ... = buffer[ i * N + j ] ...
 

#11


如果你实在不愿意写i*N+j, 那么可以用宏, 比如
#define buffer(i,j)  buffer[(i)*N+(j)]
这样的写法已经跟VB的一样了吧.

#12


看来大家基本都还是用一维数组啊,稍微简便点可以把每行首地址先算出来存起来再调用
d = (int)((1.0-q) * ((1.0-p) * (*(data+((m+ys)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys)*m_nWidth+n+1+xs)*3)))+q * ((1.0-p) * (*(data+ ((m+ys+1)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys+1)*m_nWidth+n+1+xs)*3))));
这是双线性插值的一段,是不是很傻?

#13


关注

#14


一维数组只要控制好长度和宽度甚至高度值就可以很好的实现

#15


你可以把一维数组转换成2维得啊。。。。
同时,一维得算法也可以实现,,,同上。