if not len(blurred.shape) == 2:
gray = cv2.cvtColor(blurred, cv2.COLOR_RGB2GRAY)
else:
gray = blurred
edge = cv2.Canny(gray, 50, 150)
circles = AHTforCircles(edge,center_threhold_factor=params[i]['center_threhold_factor'],score_threhold=params[i]['score_threhold'],min_center_dist=params[i]['min_center_dist'],minRad=params[i]['minRad'],
maxRad=params[i]['maxRad'],center_axis_scale=params[i]['center_axis_scale'],radius_scale=params[i]['radius_scale'],
halfWindow=params[i]['halfWindow'],max_circle_num=params[i]['max_circle_num'])
final_img = drawCircles(circles,blurred)
plt.imshow(final_img)
plt.axis('off')
plt.show()
edge = cv2.Canny(gray, 50, 150)
cv2.error: OpenCV(4.1.1)
C:\projects\opencv-python\opencv\modules\imgproc\src\canny.cpp:829:
error: (-215:Assertion failed) _src.depth() == CV_8U in function
'cv::Canny'
It would be helpfully to receive some description of your problem. What you are trying to do etc. When problem occurs. You know help us little bit before we can help you:)
An input image to the cv2.Canny() function has the wrong data type. It needs to be unsigned 8-bit integers (what OpenCV calls CV_8U), and you have something else (we can't see what from your code).
Change to cv2.Canny(gray.astype('uint8')) and that particular problem should go away.
Note though, that you might want to think about what data type your images have, and do this conversion somewhere else.
Related
I came across and figured out this dtype problem and hope it will be helpful for some.
Normally we would convert color like this, which works:
img = cv2.imread("img.jpg"), 0)
imgColor=cv2.cvtColor(img , cv2.COLOR_GRAY2BGR)
However sometimes you may normalize the image first:
img = cv2.imread("img.jpg"), 0)/255.
imgColor=cv2.cvtColor(img , cv2.COLOR_GRAY2BGR)
It will result in this error:
error: (-215) depth == CV_8U || depth == CV_16U || depth == CV_32F in function >cv::cvtColor
The point is, in the former example, dtype is uint8, while in the latter it is float64.
To correct this, add one line:
img = cv2.imread("img.jpg"), 0)/255.
img=img.astype(numpy.float32)
imgColor=cv2.cvtColor(img , cv2.COLOR_GRAY2BGR)
So this would be a similar issue that is solved but is related to another function, cv2.drawKeypoints().
This will work:
img = cv2.imread("img.jpg"), 1)
img_out = numpy.copy(img)
image_out = cv2.drawKeypoints(img,keypointList,img_out,(255,0,0),4)
However, this will not compile:
img = cv2.imread("img.jpg"), 1)/255.0
img_out = numpy.copy(img)
image_out = cv2.drawKeypoints(img,keypointList,img_out,(255,0,0),4)
Here we have this error:
error: (-5) Incorrect type of input image.
Again, division by 255 or any other processing with "img" that results in conversion to float numbers will make "img" not the correct type for drawKeypoints. Here adding img = img.astype(numpy.float32) is not helping. For input image img, it turns out that uint8 works, but float32 does not. I could not find such requirement in documentations. It is confusing that different from the issue above related to cvtColor, it complains about "type".
So to make it work:
img = cv2.imread("img.jpg"), 1)/255.0
img_out = numpy.copy(img)
img=img.astype(numpy.uint8)
image_out = cv2.drawKeypoints(img,keypointList,img_out,(255,0,0),4)
For the last line, I thought cv2.DRAW_RICH_KEYPOINTS would work as the flag(the last argument in the drawKeyPoints function). However only when I use the number 4 that it works. Any explanation will be appreciated.
I'm trying to equalize a 1 one channel image like so:
img = cv2.equalizeHist(img)
But since it's a float64 img, I get the following error:
error: (-215) _src.type() == CV_8UC1 in function equalizeHist
How do I go about this?
so basically histogram equalize is work with gray scaled images.
so if you want to do histogram equalize at colorful image you can use this code.
R, G, B = cv2.split(img)
output1_R = cv2.equalizeHist(R)
output1_G = cv2.equalizeHist(G)
output1_B = cv2.equalizeHist(B)
equ = cv2.merge((output1_R, output1_G, output1_B))
You can also use .astype(numpy.uint8).
The function equalizeHist is histogram equalization of images and only implemented for CV_8UC1 type, which is a single channel 8 bit unsigned integral type.
To convert your image to this type you can use the function convertTo with the target type (must be the same number of channels).
Make sure that the source image has the right value range, typically floating point images are interpreted as 0 = black and 1 = white and the gray range is in between, while integer images are interpreted as 0 = black and maximum value = white (which would be 255 for unsigned 8 bit type). So you'll often have to multiply your source image by 255 to fit the range. Function convertTo has a parameter to scale your values during conversion, which could give you a speed improvement compared to manual scaling.
When initialising your image variable, don't forget the flag, that solved it for me.
img = cv2.imread("my_image.png", 0)
I used 0 as the flag because I was working with a greyscale image.
After reading the image and converting it to gray. Use
img = np.float32(img)
I'm using OpenCV 3.0.0 and Python 3.4.3 to process a very large RGB image (107162,79553,3). While I'm trying to resize it using the following code:
import cv2
image = cv2.resize(img, (0,0), fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
I had this error message coming up:
cv2.error: C:\opencv-3.0.0\source\modules\imgproc\src\imgwarp.cpp:3208: error: (-215) ssize.area() > 0 in function cv::resize
I'm certain there is image content in the image array because I can save them into small tiles in jpg format. When I try to resize just a small part of the image, there is no problem and I end up with correctly resized image. (Taking a rather big chunk (50000,50000,3) still won't work, but it will work on a (10000,10000,3) chunk)
What could cause this problem and how can I solve this?
So it turns out that the problem comes from one line in modules\imgproc\src\imgwarp.cpp:
CV_Assert( ssize.area() > 0 );
When the product of rows and columns of the image to be resized is larger than 2^31, ssize.area() results in a negative number. This appears to be a bug in OpenCV and hopefully will be fixed in the future release. A temporary fix is to build OpenCV with this line commented out. While not ideal, it works for me.
And I just recently found out that the above applies only to image whose width is larger than height. For images with height larger than width, it's the following line that causes error:
CV_Assert( dsize.area() > 0 );
So this has to be commented out as well.
Turns out for me this error was actually telling the truth - I was trying to resize a Null image, which was usually the 'last' frame of a video file, so the assertion was valid.
Now I have an extra step before attempting the resize operation, which is to do the assertion myself:
def getSizedFrame(width, height):
"""Function to return an image with the size I want"""
s, img = self.cam.read()
# Only process valid image frames
if s:
img = cv2.resize(img, (width, height), interpolation = cv2.INTER_AREA)
return s, img
Now I don't see the error.
Also pay attention to the object type of your numpy array, converting it using .astype('uint8') resolved the issue for me.
I know this is a very old thread but I had the same problem which was due spaces in the images names.
e.g.
Image name: "hello o.jpg"
weirdly, by removing the spaces the function worked just fine.
Image name: "hello_o.jpg"
I am having OpenCV version 3.4.3 on MacOS.
I was getting the same error as above.
I changed my code from
frame = cv2.resize(frame, (0,0), fx=0.5, fy=0.5)
to
frame = cv2.resize(frame, None, fx=0.5, fy=0.5)
Now its working fine for me.
This type of error also takes place because the resize is unable to get the image in simple
the directory of the image may be wrong.In my case I left the forward slash during providing the location of file and this error took place after I put the slash problem was solved.
For me the following work-around worked:
split the array up into smaller sub arrays
resize the sub arrays
merge the sub arrays again
Here the code:
def split_up_resize(arr, res):
"""
function which resizes large array (direct resize yields error (addedtypo))
"""
# compute destination resolution for subarrays
res_1 = (res[0], res[1]/2)
res_2 = (res[0], res[1] - res[1]/2)
# get sub-arrays
arr_1 = arr[0 : len(arr)/2]
arr_2 = arr[len(arr)/2 :]
# resize sub arrays
arr_1 = cv2.resize(arr_1, res_1, interpolation = cv2.INTER_LINEAR)
arr_2 = cv2.resize(arr_2, res_2, interpolation = cv2.INTER_LINEAR)
# init resized array
arr = np.zeros((res[1], res[0]))
# merge resized sub arrays
arr[0 : len(arr)/2] = arr_1
arr[len(arr)/2 :] = arr_2
return arr
You can manually place a check in your code. Like this:
if result != []:
for face in result:
bounding_box = face['box']
x, y, w, h = bounding_box[0], bounding_box[1], bounding_box[2], bounding_box[3]
rect_face = cv2.rectangle(frame, (x, y), (x+w, y+h), (46, 204, 113), 2)
face = rgb[y:y+h, x:x+w]
#CHECK FACE SIZE (EXIST OR NOT)
if face.shape[0]*face.shape[1] > 0:
predicted_name, class_probability = face_recognition(face)
print("Result: ", predicted_name, class_probability)
Turns out I had a .csv file at the end of the folder from which I was reading all the images.
Once I deleted that it worked alright
Make sure that it's all images and that you don't have any other type of file
In my case I did a wrong modification in the image.
I was able to find the problem checking the image shape.
print img.shape
In my case,
image = cv2.imread(filepath)
final_img = cv2.resize(image, size_img)
filepath was incorrect, cv2.imshow didn't give any error in this case but due to wrong path cv2.resize was giving me error.
I came across the same error message while I was trying to enlarge the image size. Assigning the image type as uint8 did the work for me and I was able to resize the image 30 times of its original size. Here is an example as a reference for anyone else who has such issue.
scale_percent = 3000
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent /100)
dim = (width, height)
image = cv2.resize(img.astype('uint8'), dim, interpolation=cv2.INTER_AREA)
Same error message for me but issue was different:
The interpolation method 'INTER_AREA' was NOT compatible with int8 !
cv2.resize(frame_rgb, tuple([None, None]))
gives similar error. Notice the None values in the resizing tuple.
In my case there were some corrupt or not supported images. What i simple did is just check if it is not None than process it as shown below.
cv2.imread(image_path)
if img is not None:
cv2.resize(img,(150,150)) # You can give your own desired image size
I was working with 3 files: The python script, the image, and the trained model.
Everything worked when I moved these 3 files into their own folder instead of in the directory with the other python scripts.
I had the same error. Resizing the images resolved the issue. However, I used online tools to resize the images because using pillow to resize them did not solve my problem.
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
# Take each frame
_, frame = cap.read()
frame = cv2.medianBlur(frame,5)
cimg = cv2.cvtColor(frame,cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(frame,cv2.HOUGH_GRADIENT,1,20,
param1=50,param2=30,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
cv2.imshow('frame',cimg)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
I am trying to find circles, but my code fails OpenCV Error: Assertion failed (scn == 1 && (dcn == 3 || dcn == 4)). Any idea why? In addition, how to get coordinates of a circle?
The flag you pass to cvt Color should be cv2.COLOR_BGR2GRAY instead of cv2.COLOR_GRAY2BGR - you want convert to grayscale to have single channeled image instead of RGB 3 channeled image and that's what assertion says. (look at the docs to see what paramaters you need, an input image is clearly a 8-bit, single-channel, grayscale input image.)
Rest of the code looks ok and is an answer to second part of your question.
EDIT: (after OP having another problem with passing constant):
After changing cvtColor constant we had following code:
cimg = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
circles = cv2.HoughCircles(cimg,cv2.HOUGH_GRADIENT,1,20,
param1=50,param2=30,minRadius=0,maxRadius=0)
which actually caused another problem:
AttributeError: 'module' object has no attribute 'HOUGH_GRADIENT'
Since I'm working with OpenCV mostly with C++ and not with Python, I solved it in different way. I tried to find number equivalent of CV_HOUGH_GRADIENT constant. In turned out to be located in opencv\sources\modules\imgproc\include\opencv2\imgproc\types_c.h:
enum
{
CV_HOUGH_STANDARD =0,
CV_HOUGH_PROBABILISTIC =1,
CV_HOUGH_MULTI_SCALE =2,
CV_HOUGH_GRADIENT =3
};
That is why we can use following snippet instead of predefined constant:
circles = cv2.HoughCircles(cimg,3,1,20, param1=50,param2=30,minRadius=0,maxRadius=0)
i am trying to write a code using opencv python that automatically get canny threshold values instead of doing them manually every time.
img= cv2.imread('micro.png',0)
output = np.zeros(img.shape, img.dtype)
# Otsu's thresholding
ret2,highthresh = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
lowthresh=0.1*highthres
edges = cv2.Canny(img,output,lowthresh,highthresh)
cv2.imshow('canny',edges)
i am getting this error
"File "test2.py", line 14, in
edges = cv2.Canny(img,output,lowthresh,highthresh)
TypeError: only length-1 arrays can be converted to Python scalars"
can anyone help me to sort out this error.thankx in advance
It seems like cv2.threshold returns the detected edges, and Canny applies them to the image. The code below worked for me and gave me some nice detected edges in my image.
import cv2
cv2.namedWindow('canny demo')
img= cv2.imread('micro.png',0)
ret2,detected_edges = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
edges = cv2.Canny(detected_edges,0.1,1.0)
dst = cv2.bitwise_and(img,img,mask = edges)
cv2.imshow('canny',dst)
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()
You are running:
cv2.Canny(img,output,lowthresh,highthresh)
It is looking for
cv2.Canny(img,lowthresh,highthresh,output)
I think the ordering changed in some version, because I have seen references to both.