0

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;
        }
    }
2
  • Please provide us with a minimal reproducible example. Also a sample input/output would help. There are 3 values in each rib, how do you assign a single boolean value for them? Commented Aug 28, 2020 at 6:16
  • 1
    @Ehsan updated, please check edited post Commented Aug 28, 2020 at 6:36

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

3 Comments

got it, thank you good sir. A quick follow up question, what if I want the 2D output to be either 255, when previously it was true, or 0, when previously it was false?
@MichaelChang ((image**2).sum(2) > threshold**2)*255. Please consider accepting the answer if it resolves your issue.
@MichaelChang. Added the use of .sum(2) to my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.