2013-04-10 27 views
18

Tôi đang làm việc với bộ cảm biến Kinect và tôi đang cố gắng căn chỉnh chiều sâu và khung màu để tôi có thể lưu chúng dưới dạng hình ảnh "vừa khít" vào nhau. Tôi đã dành rất nhiều thời gian đi qua các diễn đàn msdn và tài liệu khiêm tốn của Kinect SDK và tôi hoàn toàn không có nơi nào.Kinect SDK: sắp xếp chiều sâu và khung màu

Dựa trên câu trả lời này: Kinect: Converting from RGB Coordinates to Depth Coordinates

Tôi đã hàm sau, nơi depthDatacolorData thu được từ NUI_LOCKED_RECT.pBitsmappedData là sản phẩm có chứa khung màu mới, ánh xạ tới chiều sâu phối:

bool mapColorFrameToDepthFrame(unsigned char *depthData, unsigned char* colorData, unsigned char* mappedData) 
{ 
    INuiCoordinateMapper* coordMapper; 

    // Get coordinate mapper 
    m_pSensor->NuiGetCoordinateMapper(&coordMapper); 

    NUI_DEPTH_IMAGE_POINT* depthPoints = new NUI_DEPTH_IMAGE_POINT[640 * 480]; 

    HRESULT result = coordMapper->MapColorFrameToDepthFrame(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, NUI_IMAGE_RESOLUTION_640x480, 640 * 480, reinterpret_cast<NUI_DEPTH_IMAGE_PIXEL*>(depthData), 640 * 480, depthPoints); 
    if (FAILED(result)) 
    { 
     return false; 
    }  

    int pos = 0; 
    int* colorRun = reinterpret_cast<int*>(colorData); 
    int* mappedRun = reinterpret_cast<int*>(mappedData); 

    // For each pixel of new color frame 
    for (int i = 0; i < 640 * 480; ++i) 
    { 
     // Find the corresponding pixel in original color frame from depthPoints 
     pos = (depthPoints[i].y * 640) + depthPoints[i].x; 

     // Set pixel value if it's within frame boundaries 
     if (pos < 640 * 480) 
     { 
      mappedRun[i] = colorRun[pos]; 
     } 
    } 

    return true; 
} 

Tất cả những gì tôi nhận được khi chạy mã này là một khung màu không đổi với tất cả các pixel bị xóa (trắng), trong đó depthFrame không có thông tin.

+0

Bạn đã kiểm tra ra màn hình xanh ví dụ trong Kinect cho Windows mã hóa ví dụ? http://kinectforwindows.codeplex.com/. Nó sắp xếp màu sắc và chiều sâu. –

+0

Vâng tôi có. Nó không sử dụng 'INuiCoordinateMapper' mới, nhưng một phương thức cũ hơn' INuiSensor :: NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution'. Tôi đã thử nó và nó không làm việc cho tôi hoặc là (tôi nhận được tất cả hình ảnh màu trắng). Bằng cách nào đó mảng giá trị độ sâu mà họ nhận được là USHORT (16 bit) và của tôi là 32 bit, với lý do có thể là tôi khởi tạo cảm biến Kinect của mình với các thông số khác nhau (độ sâu chỉ không có chỉ mục người chơi). Ngay cả khi tôi tạo ra một mảng các giá trị độ sâu 16 bit từ bit 32 bit thì hàm này không hoạt động đối với tôi. – jaho

+0

điều tương tự đã được giải quyết ở đây: http://stackoverflow.com/a/19905805/2521214 Kinect SDK có chức năng cho allign các hình ảnh nhưng họ đã không làm việc cho tôi ở tất cả (có một phiên bản rất cũ của kinect) vì vậy tôi đã làm nó bản thân mình ... trong liên kết đó là dữ liệu hiệu chỉnh kinect của tôi cho bạn, bạn phải tự đo nó là – Spektre

Trả lời

2

Với khung OpenNI, có đăng ký cuộc gọi tùy chọn.

IMAGE_REGISTRATION_DEPTH_TO_IMAGE - Hình ảnh sâu được chuyển đổi để có cùng điểm thuận lợi rõ ràng như hình ảnh RGB.

OpenNI 2.0 và Nite 2.0 hoạt động rất tốt để nắm bắt thông tin Kinect và có rất nhiều hướng dẫn.

Bạn có thể có một cái nhìn như thế này:

Kinect with OpenNI

Và OpenNi có một ví dụ trong SimplerViewer rằng sáp nhập sâu và màu sắc có thể bạn chỉ có thể nhìn vào đó và thử nó.

0

Đây có thể không phải là câu trả lời nhanh mà bạn đang hy vọng, nhưng việc chuyển đổi này được thực hiện thành công trong phần bổ sung ofxKinectNui cho openFrameworks (see here).

Có vẻ như ofxKinectNui đại biểu chức năng GetColorPixelCoordinatesFromDepthPixel được xác định here.

0

Tôi nghĩ rằng vấn đề là bạn đang gọi MapColorFrameToDepthFrame, khi bạn thực sự nên gọi MapDepthFrameToColorFrame.

Các khẩu súng hút thuốc là dòng mã này:

mappedRun[i] = colorRun[pos]; 

Đọc từ pos và văn bản cho i là ngược, vì pos = depthPoints[i] đại diện cho chiều sâu tọa độ tương ứng với màu phối tại i. Bạn thực sự muốn lặp qua viết tất cả các tọa độ độ sâu và đọc từ hình ảnh màu đầu vào ở tọa độ màu tương ứng.

+0

Các chức năng này có thể hoán đổi theo cách này không? –

0

Tôi nghĩ rằng trong mã của bạn có những dòng khác nhau không chính xác.

Trước hết, loại bản đồ độ sâu nào bạn chuyển đến chức năng của mình?

Dữ liệu độ sâu được storred sử dụng hai byte cho mỗi giá trị, điều đó có nghĩa là loại chính xác của con trỏ bạn nên sử dụng cho dữ liệu chuyên sâu của bạn là unsigned short.

Điểm thứ hai là từ những gì tôi đã hiểu, bạn muốn ánh xạ độ sâu khung đến khung màu, vì vậy chức năng chính xác mà bạn có để gọi từ kinect sdk là MapDepthFrameToColorFrame thay vì MapColorFrameToDepthFrame.

Cuối cùng, hàm sẽ trả về bản đồ điểm cho mỗi dữ liệu độ sâu tại vị trí [i], bạn có vị trí x và vị trí y tại đó điểm sẽ được ánh xạ.
Để thực hiện việc này, bạn không cần màu colorData pointer.

Vì vậy, chức năng của bạn nên được sửa đổi như sau:

/** Method used to build a depth map aligned to color frame 
    @param [in] depthData : pointer to your data; 
    @param [out] mappedData : pointer to your aligned depth map; 
    @return true if is all ok : false whene something wrong 
*/ 

bool DeviceManager::mapColorFrameToDepthFrame(unsigned short *depthData, unsigned short* mappedData){ 
    INuiCoordinateMapper* coordMapper; 
    NUI_COLOR_IMAGE_POINT* colorPoints = new NUI_COLOR_IMAGE_POINT[640 * 480]; //color points 
    NUI_DEPTH_IMAGE_PIXEL* depthPoints = new NUI_DEPTH_IMAGE_PIXEL[640 * 480]; // depth pixel 

    /** BE sURE THAT YOU ARE WORKING WITH THE RIGHT HEIGHT AND WIDTH*/ 
    unsigned long refWidth = 0; 
    unsigned long refHeight = 0; 
    NuiImageResolutionToSize(NUI_IMAGE_RESOLUTION_640x480, refWidth, refHeight); 
    int width = static_cast<int>(refWidth ); //get the image width in a right way 
    int height = static_cast<int>(refHeight); //get the image height in a right way 

    m_pSensor>NuiGetCoordinateMapper(&coordMapper); // get the coord mapper 
    //Map your frame; 
    HRESULT result = coordMapper->MapDepthFrameToColorFrame(NUI_IMAGE_RESOLUTION_640x480, width * height, depthPoints, NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, width * height, colorPoints); 
    if (FAILED(result)) 
     return false; 

    // apply map in terms of x and y (image coordinates); 
    for (int i = 0; i < width * height; i++) 
     if (colorPoints[i].x >0 && colorPoints[i].x < width && colorPoints[i].y>0 && colorPoints[i].y < height) 
      *(mappedData + colorPoints[i].x + colorPoints[i].y*width) = *(depthData + i); 

    // free your memory!!! 
    delete colorPoints; 
    delete depthPoints; 
    return true; 
} 



Hãy chắc chắn rằng mappedData của bạn đã được khởi tạo trong cách chính xác, ví dụ như sau.

mappedData = (USHORT*)calloc(width*height, sizeof(ushort)); 


Hãy nhớ rằng Kinect SDK không cung cấp một chức năng class chính xác giữa màu sắc và chiều sâu dữ liệu.

Nếu bạn muốn căn chỉnh chính xác giữa hai hình ảnh, bạn nên sử dụng mô hình hiệu chuẩn. Trong trường hợp đó tôi đề nghị bạn sử dụng Hộp công cụ hiệu chỉnh Kinect, dựa trên mô hình hiệu chuẩn Heikkilä.

Bạn có thể tìm thấy nó trong liên kết sau:
http://www.ee.oulu.fi/~dherrera/kinect/.

-1

Trước hết, bạn phải hiệu chỉnh thiết bị của mình. Điều đó có nghĩa, bạn nên hiệu chỉnh RGB và cảm biến hồng ngoại và sau đó tìm sự chuyển đổi giữa RGB và IR. Một khi bạn biết thông tin này, bạn có thể áp dụng các chức năng:

RGBPoint = RotationMatrix * DepthPoint + TranslationVector 

Kiểm tra OpenCV, dự án ROS để biết thêm chi tiết về nó.

Extrinsic Calibration

Intrinsic Calibration

+0

nơi tôi có thể tìm thấy thông tin liên quan đến việc chuyển đổi? – ThunderWiring

+0

@ThunderWiring tại đây bạn tìm thêm thông tin chi tiết: http://wiki.ros.org/openni_launch/Tutorials/IntrinsicCalibration và tại đây: http://wiki.ros.org/openni_launch/Tutorials/ExtrinsicCalibration – madduci

Các vấn đề liên quan