1

Trying to count number of objects in .npy image file

import numpy as np
img=np.load('A03_00Ac_Object Identities.npy')
from matplotlib import pyplot as plt
plt.imshow(img,cmap='gray')

A03_00Ac_Object Identities.npy image

import cv2
plt.imshow(img, cmap='gray')
blur = cv2.GaussianBlur(gray, (11, 11), 0)
canny = cv2.Canny(blur, 30, 40, 3)
plt.imshow(canny, cmap='gray')
dilated = cv2.dilate(canny, (1, 1), iterations=0) 
plt.imshow(dilated, cmap='gray')
(cnt, hierarchy) = cv2.findContours(
dilated.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.drawContours(rgb, cnt, -1, (0, 255, 0), 2)
plt.imshow(rgb)
print("No of circles: ", len(cnt))

Received Error

Traceback (most recent call last)
Input In [32], in <cell line: 1>()
----> 1 blur = cv2.GaussianBlur(img, (11, 11), 0)

error: OpenCV(4.5.4) :-1: error: (-5:Bad argument) in function 'GaussianBlur'
> Overload resolution failed:
>  - src data type = 8 is not supported
>  - Expected Ptr<cv::UMat> for argument 'src'

Please help me on this...Opencv Ref: How to count objects in image using python?

Nandhini
  • 53
  • 1
  • 2
  • 11
  • 1
    why does the Traceback mention `GaussianBlur` but your code doesn't contain it? what is `type(img)`, what is `img.dtype` and `img.shape`? – Christoph Rackwitz Apr 06 '22 at 08:51
  • Sorry, my mistake missed that part of code... but for any CV2 functions I am receiving the same error. dtype is uint32 – Nandhini Apr 06 '22 at 09:03
  • and When I type img.shape() received the following "TypeError: 'tuple' object is not callable" – Nandhini Apr 06 '22 at 09:05
  • also when I tried to convert it into a .jpg file.. an object in an image is missing. Please suggest me, handle this data in the right way. Thank you – Nandhini Apr 06 '22 at 09:11
  • I asked for `img.shape`, not `img.shape()`. anyway, if dtype is uint32, that's likely unsuitable for the OpenCV APIs you call there. they don't work on arbitrary types. some assume uint8 or float32. – Christoph Rackwitz Apr 06 '22 at 09:17
  • Shape of the image is (1376, 1539, 1).. ok is there any way where I can further proceed to count the number of objects.. other than opencv – Nandhini Apr 06 '22 at 09:23
  • 1
    what's the value of `img.max()`? if it's 255 or less, use `img.astype(np.uint8)`. or you could just use `np.uint8(img > 0)` (a mask) and give that to opencv. – Christoph Rackwitz Apr 06 '22 at 09:34
  • img.max() is 2, min is 0.. thank you.. I tried this "img.astype(np.uint8)" it is working well... Thank you so much, Christoph....you made my day... – Nandhini Apr 06 '22 at 09:40
  • 1
    I've turned the conclusions into an answer. for the data you have, Canny is harmful. you can just apply findContours to the data. you could also apply `connectedComponentsWithStats` to your data. – Christoph Rackwitz Apr 06 '22 at 10:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/243645/discussion-between-nandhini-and-christoph-rackwitz). – Nandhini Apr 06 '22 at 10:13

1 Answers1

1

Many OpenCV functions expect specific data types. Your array has type np.uint32/CV_32U. GaussianBlur won't accept that. It will accept np.uint8/CV_8U.

If the range of your array's values fits in uint8 (check whether img.max() <= 255), you can convert it using

img_u8 = img.astype(np.uint8)

If your array's values happen to exceed uint8 range but the values don't matter, you can simply "threshold" the data and use the result:

mask = np.uint8(img > 0)
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36