Search code examples
c++pixelimage-scalingdownsampling

C++ How to best scale image by dropping pixels


I am capturing a frame of data from an imager with a resolution of 102 x 77. I want to downsample this to 80 x 60. Quality is not the main concern but ease of implementation and speed are.

I believe I can accomplish this by roughly dropping every 4th pixel:

>>> 80.0 / 102.0 
0.7843137254901961
>>> 
>>> 60.0 / 77.0 
0.7792207792207793
>>> 
>>> 102 * ( 0.75 )
76.5
>>> 77 * ( 0.75 )
57.75

Since it is not exactly 4, how do I account for this? What's the best way drop the number of pixels I required to get 80 x 60? Thanks.

Code where I iterate pixels:

// Initialize data store for frame pixel data
vector<quint8> data;
data.resize(frame.getHeight() * frame.getWidth());

// Try to get a frame
forever
{

    // Request a frame and check return status
    if ( !getRawFrame(frame) ) {

        qDebug() << "************************";
        qDebug() << "Failed Capture Attempt!";
        qDebug() << "************************";

        // Failed - try again
        continue;

    }

    // Get the height and width
    int h = frame.getHeight();
    int w = frame.getWidth();

    // Get the frame raw data
    vector<quint8> rawdata = frame.getRawData();

    // Iterate the pixels
    for (int y = 0; y < h; y++)
    {
        for (int x = 0; x < w; x++)
        {

            // Extract
            quint8 pixelValue = reinterpret_cast<quint8*>(rawdata.data())[y*w+x];
            int convertToInt = int(pixelValue);

            /// do stuff on pixel data

            // Downconvert
            pixelValue = convertToInt;

            // Assign
            data[y*w+x] = pixelValue;

        }
    }

    // Assign the data to the Frame now
    frame.setData(data);

    // Done with capture loop
    break;

}

Solution

  • Having a smaller resolution than what you need after dropping pixels is obviously not what you want. And since you cannot just magically get some of the pixels back I would try not dropping that many in the first place.

    My approach in this case would be dropping every fifth pixel. This would leave you with a resolution of 81x61. Now you can just remove 1 more line and one more coloumn of pixels and you're done. That's the fastest and easiest that I can think of.