Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

[C++] Efficient element-by-element pixel access?

Hello,

I know this has been asked many times and I've gone over the docs here but cannot seem to find an answer to my specific issue. I am trying to map the results from k-means clustering back into an image with reduced colors.

My old code works and does this using the Mat.at accessor, but it is very slow. I am trying to re-write this using pointers to improve performance, but right now the clustered image has many diagonal lines and the colors/pixels are not in the right place.

This works but is slow

for( int y = 0; y < resized.rows; y++ ){
    for( int x = 0; x < resized.cols; x++ ){
        {
            pixelPos =y + x*resized.rows;
            cluster_idx = labels.at<int>(pixelPos,0);
            clusteredImg.at<Vec3b>(y,x)[0] = centers.at<float>(cluster_idx, 0);
            clusteredImg.at<Vec3b>(y,x)[1] = centers.at<float>(cluster_idx, 1);
            clusteredImg.at<Vec3b>(y,x)[2] = centers.at<float>(cluster_idx, 2);
        }
    }

}

This should be much faster, but is not working yet

for (int i = 0; i < resized.rows; ++i)
{
    cv::Vec3b* destPix = clusteredImg.ptr<cv::Vec3b>(i);
    int* labelPix = labels.ptr<int>(i);
    for (int j = 0; j < resized.cols; ++j)
    {
        cluster_idx = *labelPix++;
        float * centroidPtr = centers.ptr<float>(cluster_idx);

            destPix[j][0] = *centroidPtr++;
            destPix[j][1] = *centroidPtr++;
            destPix[j][2] = *centroidPtr++;
    }
}

Sorry if this is a stupid question, I am very new to C++.

I'm sure I have something wrong with how the destination data is assigned. I've checked the source data by printing debug statements and that seems to be correct.

[C++] Efficient element-by-element pixel access?

Hello,

I know this has been asked many times and I've gone over the docs here but cannot seem to find an answer to my specific issue. I am trying to map the results from k-means clustering back into an image with reduced colors.

My old code works and does this using the Mat.at accessor, but it is very slow. I am trying to re-write this using pointers to improve performance, but right now the clustered image has many diagonal lines and the colors/pixels are not in the right place.

This works but is slow

for( int y = 0; y < resized.rows; y++ ){
    for( int x = 0; x < resized.cols; x++ ){
        {
            pixelPos =y + x*resized.rows;
            cluster_idx = labels.at<int>(pixelPos,0);
            clusteredImg.at<Vec3b>(y,x)[0] = centers.at<float>(cluster_idx, 0);
            clusteredImg.at<Vec3b>(y,x)[1] = centers.at<float>(cluster_idx, 1);
            clusteredImg.at<Vec3b>(y,x)[2] = centers.at<float>(cluster_idx, 2);
        }
    }

}

This should be much faster, but is not working yetEDIT: The below code is working I had a silly mistake where I forgot that labels was M*Nx1 rather than MxNx1.

If there is any room for improvement please let me know!

for (int i = 0; i < resized.rows; ++i)
{
    cv::Vec3b* destPix = clusteredImg.ptr<cv::Vec3b>(i);
    int* labelPix = labels.ptr<int>(i);
    for (int j = 0; j < resized.cols; ++j)
    {
        pixelPos = i + j*resized.rows;
        cluster_idx = *labelPix++;
*labels.ptr<int>(pixelPos,0);
        float * centroidPtr = centers.ptr<float>(cluster_idx);

            destPix[j][0] = *centroidPtr++;
            destPix[j][1] = *centroidPtr++;
            destPix[j][2] = *centroidPtr++;
    }
}

Sorry if this is a stupid question, I am very new to C++.

I'm sure I have something wrong with how the destination data is assigned. I've checked the source data by printing debug statements and that seems to be correct.

click to hide/show revision 3
No.3 Revision

updated 2015-05-05 16:41:29 -0600

SR gravatar image

[C++] Efficient element-by-element pixel access?

Hello,

I know this has been asked many times and I've gone over the docs here but cannot seem to find an answer to my specific issue. I am trying to map the results from k-means clustering back into an image with reduced colors.

My old code works and does this using the Mat.at accessor, but it is very slow. I am trying to re-write this using pointers to improve performance, but right now the clustered image has many diagonal lines and the colors/pixels are not in the right place.

This works but is slow

for( int y = 0; y < resized.rows; y++ ){
    for( int x = 0; x < resized.cols; x++ ){
        {
            pixelPos =y + x*resized.rows;
            cluster_idx = labels.at<int>(pixelPos,0);
            clusteredImg.at<Vec3b>(y,x)[0] = centers.at<float>(cluster_idx, 0);
            clusteredImg.at<Vec3b>(y,x)[1] = centers.at<float>(cluster_idx, 1);
            clusteredImg.at<Vec3b>(y,x)[2] = centers.at<float>(cluster_idx, 2);
        }
    }

}

EDIT: The below code is working I had a silly mistake where I forgot that labels was M*Nx1 rather than MxNx1.

If there is any room for improvement please let me know!

for (int i = 0; i < resized.rows; ++i)
{
    cv::Vec3b* destPix = clusteredImg.ptr<cv::Vec3b>(i);
    int* labelPix = labels.ptr<int>(i);
    for (int j = 0; j < resized.cols; ++j)
    {
        pixelPos = i + j*resized.rows;
        cluster_idx = *labels.ptr<int>(pixelPos,0);
        float * centroidPtr = centers.ptr<float>(cluster_idx);

         destPix[j][0] = *centroidPtr++;
         destPix[j][1] = *centroidPtr++;
         destPix[j][2] = *centroidPtr++;
    }
}

Sorry if this is a stupid question, I am very new to C++.

I'm sure I have something wrong with how the destination data is assigned. I've checked the source data by printing debug statements and that seems to be correct.