You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Vimba C API获取图像灰度值并计算像素质心

Vimba C API灰度图像质心计算问题

我正在使用Vimba C语言API,基于官方的SynchronousGrab示例修改代码,首次使用Visual Studio开发。需求是在相机采集的深色灰度图中,找到较亮像素云的质心,目前在适配更大尺寸图像时遇到坐标计算错误的问题。

相关代码与定义

函数内变量声明

VmbError_t SynchronousGrab( const char* pCameraID, const char* pFileName, int threshold )
{
VmbFrame_t          frame;                                  // The frame we capture
VmbUint32_t         j                   = 0;                //CUSTOM
VmbUint32_t         k                   = 0;                //CUSTOM
unsigned char*      CurSrc              = 0;                //CUSTOM
int                 arraysize           = 0;                //CUSTOM
float*              coordY              = 0;                //CUSTOM
float*              coordX              = 0;                //CUSTOM
float*              intensity           = 0;                //CUSTOM
float               centroid_x          = -1;               //CUSTOM
float               centroid_y          = -1;               //CUSTOM

VmbFrame_t结构体定义

typedef struct
{
    //----- In -----
    void*               buffer;             // Comprises image and ancillary data
    VmbUint32_t         bufferSize;         // Size of the data buffer

    void*               context[4];         // 4 void pointers that can be employed by the user (e.g. for storing handles)

    //----- Out -----
    VmbFrameStatus_t    receiveStatus;      // Resulting status of the receive operation
    VmbFrameFlags_t     receiveFlags;       // Flags indicating which additional frame information is available

    VmbUint32_t         imageSize;          // Size of the image data inside the data buffer
    VmbUint32_t         ancillarySize;      // Size of the ancillary data inside the data buffer

    VmbPixelFormat_t    pixelFormat;        // Pixel format of the image

    VmbUint32_t         width;              // Width of an image
    VmbUint32_t         height;             // Height of an image
    VmbUint32_t         offsetX;            // Horizontal offset of an image
    VmbUint32_t         offsetY;            // Vertical offset of an image

    VmbUint64_t         frameID;            // Unique ID of this frame in this stream
    VmbUint64_t         timestamp;          // Timestamp set by the camera
} VmbFrame_t;

自定义像素分析代码

err = VmbCaptureFrameWait( cameraHandle, &frame, nTimeout );
if ( VmbErrorSuccess == err )  //Existing SynchronousGrab code
    {   

    CurSrc = (unsigned char*)frame.buffer;                                                                                   
    for (k = 0; k < frame.height; k++) {
        for (j = 0; j < frame.width; j++) {
            if (*(CurSrc+k * frame.width + j) >= threshold) {
                coordY = realloc(coordY, ++arraysize * sizeof(*coordY));
                coordX = realloc(coordX, arraysize * sizeof(*coordX));
                intensity = realloc(intensity, arraysize * sizeof(*intensity));
                coordY[arraysize - 1] = k * (*(CurSrc + k * frame.width + j));
                coordX[arraysize - 1] = j * (*(CurSrc + k * frame.width + j));
                intensity[arraysize - 1] = (*(CurSrc + k * frame.width + j));
            }
        }
    }
    if (arraysize != 0) {
        centroid_x = getSum(coordX, arraysize) / getSum(intensity, arraysize);
        centroid_y = getSum(coordY, arraysize) / getSum(intensity, arraysize);
        printf("Centroid is in (%.1f,%.1f)\n", centroid_x, centroid_y);
        free(coordX);
        free(coordY);
        free(intensity);
        arraysize = 0;
    }

    if ( VmbFrameStatusComplete == frame.receiveStatus )  //Existing SynchronousGrab code

自定义getSum函数

int getSum(float* head, int size) {                         //CUSTOM FUNCTION   
    int i;
    int sum = 0;
    for (i = 0; i < size; i++) {
        sum = sum + head[i];
    }
    return sum;
}

问题现象

  • 原算法在固定1440×1080尺寸图像上测试可行,但适配更大尺寸图像后,质心坐标计算错误。
  • 最初误用固定值1440代替frame.width,修改后首次运行时centroid_y为负数(但赋值为两个正数的乘积),后续运行转为正数,但坐标误差达1900像素左右。
  • 质心坐标存在小幅波动,怀疑由相机或工作台振动导致,但主要问题是坐标偏移错误。

怀疑点与补充信息

  • 怀疑frame.buffer并非指向长度为frame.width * frame.height的灰度像素数组,但因相机设置访问受限,暂时无法采用暴力内存排查方案。
  • 事后发现代码位置错误:质心计算逻辑应该放在VmbFrameStatusComplete == frame.receiveStatus的判断分支内,当前代码可能读取了未完全接收的图像数据。

内容的提问来源于stack exchange,提问作者ATSlooking4things

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:35:29