Michael Chang
Michael Chang

Reputation: 27

create 2D array based on 3D array numpy

Whats the most efficient way to create a 2D array based on a 3D array? I have the following input 3D array, which encodes the rgb information of a picture:

[[[255,255,255], [255,255,255], [255,255,255], ... ]]

i want to create a new 2D array which is a mask essentially, checking if the rgb values yield above a certain threshold:

[[true, false, true, false, ...]]

When i operate on each of the rgb values, I am doing a series of multiplications, additions and sqrts, and the final value of this operation determines the values of the 2D array output, either true or false.

Thanks in advance.

EDIT: I am trying to convert this C++ code to python:

cv::Mat diffImage;
cv::absdiff(backgroundImage, currentImage, diffImage);

cv::Mat foregroundMask = cv::Mat::zeros(diffImage.rows, diffImage.cols, CV_8UC1);

float threshold = 30.0f;
float dist;

for(int j=0; j<diffImage.rows; ++j)
    for(int i=0; i<diffImage.cols; ++i)
    {
        cv::Vec3b pix = diffImage.at<cv::Vec3b>(j,i);

        dist = (pix[0]*pix[0] + pix[1]*pix[1] + pix[2]*pix[2]);
        dist = sqrt(dist);

        if(dist>threshold)
        {
            foregroundMask.at<unsigned char>(j,i) = 255;
        }
    }

Upvotes: 0

Views: 58

Answers (1)

Frank Yellin
Frank Yellin

Reputation: 11240

I think what you're looking for is

np.sqrt(np.sum(image ** 2, axis=2)) > threshold

Even better would be to write:

np.sum(image**2, axis=2) > threshold ** 2

since squaring the threshold is faster than taking the square root of every element in the array.

I think you can also use axis=-1, so that it always sums along the final axis, regardless of the dimensions of the array.

@MichaelChang reminds me that sum is both a function and a method. This could be rewritten even more simply as:

(images**2).sum(axis=2) > threshold ** 2

Upvotes: 1

Related Questions