最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Removing rows from numpy 3D array based on last element - Stack Overflow

programmeradmin4浏览0评论

What I'm trying to do is essentially removing all rows h,s in a 3D numpy array a if a[h,s,v] = some value for all v

More specifically, I have a loaded image from cv2 which contains some transparent pixels. I'd like to create an HSV histogram without including the transparent pixels (i.e. k=255)

Here's what I have now:

import cv2
import numpy as np

IMAGE_FILE = './images/2024-11-17/00.png'  # load image with some transparent pixels

# Read image into HSV
image = cv2.imread(IMAGE_FILE)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# Remove all pixels with V = 255
hsv_removed_transparency = []
i = np.where(hsv[:, :, 2] == 255)  # indices of pixels with V = 255
for i1 in range(len(i[0])):
    hsv_removed_transparency.append(np.delete(hsv[i[0][i1]], i[1][i1], axis=0)

What I'm trying to do is essentially removing all rows h,s in a 3D numpy array a if a[h,s,v] = some value for all v

More specifically, I have a loaded image from cv2 which contains some transparent pixels. I'd like to create an HSV histogram without including the transparent pixels (i.e. k=255)

Here's what I have now:

import cv2
import numpy as np

IMAGE_FILE = './images/2024-11-17/00.png'  # load image with some transparent pixels

# Read image into HSV
image = cv2.imread(IMAGE_FILE)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# Remove all pixels with V = 255
hsv_removed_transparency = []
i = np.where(hsv[:, :, 2] == 255)  # indices of pixels with V = 255
for i1 in range(len(i[0])):
    hsv_removed_transparency.append(np.delete(hsv[i[0][i1]], i[1][i1], axis=0)
Share Improve this question edited Jan 19 at 11:14 Christoph Rackwitz 15.4k5 gold badges39 silver badges51 bronze badges asked Jan 19 at 0:37 Omaro_IBOmaro_IB 4252 gold badges4 silver badges14 bronze badges 2
  • 1 You can't. In a 2D array, you can remove a whole row or a whole column. But you can't remove a single element. That would not be a 2D array anymore. Likewise, in a 3D array, you can remove a whole plane (plane h=?, or plane s=?, or plane v=?), but you can't remove a single row (if you are convinced of what I said about 2D array, then, it is easy to be convinced about 3D array: a 3D array, after all, is nothing more than a 2D array of "rows") – chrslg Commented Jan 19 at 7:16
  • 1 Now, you've layed out your XY-problem yourself. Your real question isn't "remove a row from a 3D array", your real question is "create a hsv histogram without including transparent pixels". That is probably possible. But you need to clarify what form that histogram would take, and how you intend to build it. But roughly: just don't count pixels with v=255. For example by counting only pixels of np.where(hsv[:,:,2]!=255) – chrslg Commented Jan 19 at 7:24
Add a comment  | 

1 Answer 1

Reset to default 1

If you want to compute a histogram with a mask, just do that. No need to alter the image. cv2.calcHist takes a mask parameter:

import cv2

image = cv2.imread('squirrel_cls.jpg') # https://raw.githubusercontent.com/opencv/opencv/refs/heads/4.x/samples/data/squirrel_cls.jpg
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# add some more values with V = 255
hsv[100:350, 150:350, 2] = 255

# compute the histogram for the Hue
h_hist_all = cv2.calcHist([hsv], [0], None, [256], [0, 256])
# compute the histogram for the Saturation
s_hist_all = cv2.calcHist([hsv], [1], None, [256], [0, 256])

mask = (hsv[..., 2] != 255).astype(np.uint8)
# compute the histogram for the Hue with mask
h_hist = cv2.calcHist([hsv], [0], mask, [256], [0, 256])
# compute the histogram for the Saturation with mask
s_hist = cv2.calcHist([hsv], [1], mask, [256], [0, 256])


import matplotlib.pyplot as plt

plt.plot(h_hist_all, label='H (all)')
plt.plot(h_hist, label='H (mask)')
plt.plot(s_hist_all, label='S (all)')
plt.plot(s_hist, label='S (mask)')
plt.legend()

Output:

For a 2D histogram (H vs S):

f, (ax1, ax2) = plt.subplots(ncols=2, sharey=True)

ax1.imshow(np.log(cv2.calcHist([hsv], [0, 1], None, [256, 256], [0, 256, 0, 256])),
           cmap='Greys')
ax2.imshow(np.log(cv2.calcHist([hsv], [0, 1], mask, [256, 256], [0, 256, 0, 256])),
           cmap='Greys')
ax1.set_title('all')
ax2.set_title('mask')
ax1.set_xlabel('H')
ax1.set_ylabel('S')

Output:

Likewise, if you want to use np.histogram, just filter out the values from the channel:

h_hist_mask, bins = np.histogram(hsv[..., 0][hsv[..., 2] != 255])

Used images:

发布评论

评论列表(0)

  1. 暂无评论