mmmmm5
mmmmm5

Reputation: 151

In python opencv, why is array[:] and array different?

I'm a python and opencv newbie so bear with me if simple question.

In the code below, how come the 2 array calculations provide different answer?

(a) channel[:] = channel * normalizedInverseAlpha
(b) channel = channel * normalizedInverseAlpha

How come (a) and (b) are the not the same?

normalizedInverseAlpha = (1.0 / 255) * (255 - graySrc)
channels = cv2.split(src)
for channel in channels:
    channel[:] = channel * normalizedInverseAlpha
    #this is different from channel = channel * normalizedInverseAlpha. Why?

cv2.merge(channels, dst)

Upvotes: 0

Views: 83

Answers (1)

Kinght 金
Kinght 金

Reputation: 18331

We use [:] to do array slice-op for every element in the array.

(1)

for channel in channels: 
   channel[:] = channel * alpha

Assign the result of channel * alpha to original channel.

(2)

for channel in channels: 
    channel = channel * alpha

Create a new variable named channel and assign the result of channel * alpha to new channel, has no effect on the original.


Here I do an experiment:

#!/usr/bin/python3
# 2018.01.20 19:28:35 CST
import cv2
import numpy as np

img = cv2.imread("test.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

alpha = (1.0 / 255) * (255 - gray)

channels = cv2.split(img)

for channel in channels:
    print("Before:", id(channel), channel.shape, channel.dtype)
    channel[:] = channel * alpha
    print("After:", id(channel), channel.shape, channel.dtype)

dst1 = cv2.merge(channels)


channels = cv2.split(img)
for channel in channels:
    print("Before:", id(channel), channel.shape, channel.dtype)
    channel = channel * alpha
    print("After:", id(channel), channel.shape, channel.dtype)

dst2 = cv2.merge(channels)

dst2 = cv2.merge(channels)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.waitKey()

The output:

Before: 140130414391088 (480, 480) uint8
After: 140130414391088 (480, 480) uint8
Before: 140130413969616 (480, 480) uint8
After: 140130413969616 (480, 480) uint8
Before: 140130413969776 (480, 480) uint8
After: 140130413969776 (480, 480) uint8
Before: 140130413969936 (480, 480) uint8
After: 140130414391088 (480, 480) float64
Before: 140130413970016 (480, 480) uint8
After: 140130414391088 (480, 480) float64
Before: 140130413970096 (480, 480) uint8
After: 140130414391088 (480, 480) float64

We can clearly see the id of channel keeps the same then do channel[:] = channel * alpha, so assign on the original channel; while id changes when doing channel = channel * alpha, so assign on the new channel, keep the original.


The result is as expected:

enter image description here

Upvotes: 1

Related Questions