Home > database >  (-215:Assertion failed) total >= 0 && (depth == CV_32F || depth == CV_32S) in function 'cv::
(-215:Assertion failed) total >= 0 && (depth == CV_32F || depth == CV_32S) in function 'cv::

Time:10-22

co_ords = np.column_stack(np.where(img > 0))
    angle = cv2.minAreaRect(co_ords)[-1]
    if angle < -45:
        angle = -(90   angle)
    else:
        angle = -angle

co_ords = np.column_stack(np.where(img > 0)) returns

[[   0    0    0]
 [   0    0    1]
 [   0    0    2]
 ...
 [7014 4960    0]
 [7014 4960    1]
 [7014 4960    2]]

angle = cv2.minAreaRect(co_ords)[-1]

this code return error

Error on line 43 error OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\convhull.cpp:143: error: (-215:Assertion failed) total >= 0 && (depth == CV_32F || depth == CV_32S) in function 'cv::convexHull'

And why error show this path D:\a\opencv-python\ i dont have such And how to fix this error?

CodePudding user response:

minAreaRect needs 2D coordinates, that is array of [x,y] coordinates in the form array([[x,y], [x,y], [x,y]...])

You fed it with an array 3D coordinates, namely of y, x and component (0 for blue, 1 for green, 2 for red) coordinates.

img is a BGR image. So a 3D array, each img[y,x,c] being a 0..255 int. So img[100,50,1] is the green component of pixels at line 100, column 50.

So if you ask which of those components are greater than 100, you get what you asked. A list of (y,x,c) for which this is greater than 100.

Now, depending on what you really want to do, you may want to just skip the component before using minAreaRect (and swap x and y, since, cf Christoph's comment, minAreaRect is expecting x,y coordinates, while np.where is giving y,x,components)

angle = cv2.minAreaRect(co_ords[:,(1,0)])[-1]

That list the x,y part of each y,x,c for which img[y,x,c]>=100. Which means that you have [x,y] for each pixel for which either red, or green or blue component is ≥100. Note that some [x,y] may be duplicated or tripled in that list, if more than one component is ≥100, for example for white pixels. It doesn't change the result of minAreaRect, but certainly changes the computation time.

What you really want to do, is probably decide the real condition you need to apply to np.where on pixels, not components.

For example

co_ords = np.column_stack(np.where(img[:,:,0]>=100))[:,(1,0)]

to select pixels whose blue component is ≥100. Since what is given to np.where is a 2d array, (same shape as img[:,:,0]), you get 2D coordinates. (Note that, since Christoph's comment, we still need to swap the x and y. But this time there is no component to drop)

Or

co_ords = np.column_stack(np.where(img.sum(axis=2)>=300))[:,(1,0)]

Which select coordinates in which, on average, components are ≥100 (grey level is ≥100).

But, well, whatever your criteria is, you need a list of pixels coordinates, not including which component is concerned.

If you want to avoid the x,y swap, you can also just drop it: just the angle you get is changed (90°-θ instead of θ)

So you could also, for example

co_ords = np.column_stack(np.where(img.sum(axis=2)>=300))
angle = 90 - cv2.minAreaRect(co_ords)[-1]
  • Related