I am new to computer vision and image processing and am using this code
from skimage.feature import hog
hog_list, hog_img = hog(test_img_gray,
orientations=8,
pixels_per_cell=(16, 16), cells_per_block=(1, 1),
block_norm='L1',
visualise=True,
feature_vector=True)
plt.figure(figsize=(15,10))
plt.imshow(hog_img)
to get this HOG visualization image
I have 2 questions at this point:
When I try to save this image (as a .pdf or .jpg) the resulting image is pure black. Converting this image to PIL format and examining it with
hog_img_pil = Image.fromarray(hog_img)
hog_img_pil.show()
still shows the image as pure black. Why is this happening and how can I fix it?
When I try to run this code
hog_img = cv2.cvtColor(hog_img, cv2.COLOR_BGR2GRAY)
to convert the image to grayscale I get the error error: (-215) depth == CV_8U || depth == CV_16U || depth == CV_32F in function cvtColor. What do I need to do to get this image in grayscale and why would this be happening?
As additional information, running hog_img.shape returns (1632, 1224) which is just the size of the image, which I had initially interpreted to mean that the image is already is already in grayscale (since it appears to be lacking a dimension for color channel). However, when I then tried to run
test_img_bw = cv2.adaptiveThreshold(
src=hog_img,
maxValue=255,
adaptiveMethod=cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
thresholdType=cv2.THRESH_BINARY,
blockSize=115, C=4)
I got the error error: (-215) src.type() == CV_8UC1 in function adaptiveThreshold which this answer seems to indicate means that the image is not in grayscale.
Finally, another bit of useful information is that running print(hog_img.dtype) on the image returns float64.
I will continue to debug, in the meantime
Thanks for any thoughts :)
Inverting the image with hog_img_inv = cv2.bitwise_not(hog_img) and using
plt.figure(figsize=(15,10))
plt.imshow(hog_img_uint8_inv)
showed that the lines were in fact there but are very faint (I've included the image here for comletness, but you can barley see it (but trust me, it's there)). I will have to do some more processing of the image to get the lines more distinguishable.
Running print(hog_img.dtype) showed that the dtype was float64 when (I think) it should have been uint8. I fixed this by running hog_img_uint8 = hog_img.astype(np.uint8) which seems to have fixed the problem with passing the image to other algorithms (eg. cv2.adaptiveThreshold).
If had the same problem. But if you look inside the docu, they also use this code for better visualisation:
# Rescale histogram for better display
hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 0.02))
But I still have the same problem. Visualisation with matplotlib is no problem. saving the image with opencv (or skimage) saves only a black image...
Related
I am trying to visualize a tiff image in an ipython notebook using the following code, import statements are ignored for clarity purposes.
from PIL import Image
orig_img_path = os.path.join("path/to/tiff/0.tiff")
img_orig = Image.open(orig_img_path,"r")
plt.imshow(img_orig)
plt.show()
The above snippet just shows me the following black image -
I know that the image pixel values are non-zero since I can open the original images on my MacBook and they look like the following -
I also double check that the pixel values are nonzero by using the following code of casting the PIL image to an np array using the following code and printing the array out -
img_arr = np.array(img_orig)
print(img_arr)
which gives me the following output -
I think I know what the issue is as well - that the matplotlib pyplot thinks that this is a PNG image or something like that and as we can see the pixel values are very small to be perceivable by the human eyes. I mean I can simply multiply the image by 255 which gives the following image as expected, although scaling by 255 is not entirely right since the pixel values need to be normalized for the minimum to corrspond to 0 and max to 255 assuming mat plot lib thinks that it is showing a PNG image -
I would like to know if there is a better way of doing so rather than me manually doing it all the time, any native way of displaying tiff in a Jupyter/ipython notebook which preserves all the good properties of tiff images such as floating point numbers etc.
Thanks and please let me know if anything is unclear.
Edit 1: Link to the original file is here - https://drive.google.com/file/d/1O1-QM6aeU5-QZhT36vOMjDND2vkZNgqB/view?usp=sharing
-- Megh
If you share your original image in .tiff format the solution might be more precise.
You are reading the image pixels as type float: 0-1, and after that, you parse them as uint8 : 0-255 which will turn all pixels values into 0 or 1: Black or almost Black
You can try the following approach to read your image (supposedly Black and White) and parse it:
import cv2
gray = cv2.imread("path/to/tiff/0.tiff", cv2.IMREAD_UNCHANGED)
cv2.namedWindow("MyImage", cv2.WINDOW_NORMAL)
cv2.imshow("MyImage", gray)
cv2.waitKey(0)
What is the range of values that you expect in that image? Did you do any preprocessing to it?
The image you are trying to display in matplotlib contains negative values. Visualizing works well for any kind of uint8 data (Grayscale and RGB) and data in the range of 0 - 1. Your displaying issue can be addressed by adding the min value of the image and then dividing by the max value (effectively normalizing your data to the range 0-1).
[...]
img = np.array(img_orig, dtype=float)
img += abs(np.min(img))
img /= np.max(img)
plt.imshow(img)
plt.show()
I've tried overlaying two images in openCV both in openCV and in PIL, but to no avail. I'm using a 1000x1000x3 array of np.zeros for the background (aka, a black background) and this random image of my monitor, but I really can't get it to work for some reason unbeknownst to me.
Trying with OpenCV only: (result(if you pay attention, you can see a couple of weird lines and dots in the middle))
base_temp = np.zeros((1000,1000,3))
foreground_temp = cv2.imread('exampleImageThatILinkedAbove.png')
base_temp[offset_y:offset_y+foreground_temp.shape[0], offset_x:offset_x+foreground_temp.shape[1]] = foreground_temp
Trying with PIL: (The result is literally the same as the OpenCV version)
base_temp = cv2.convertScaleAbs(self.base) #Convert to uint8 for cvtColor
base_temp = cv2.cvtColor(base_temp, cv2.COLOR_BGR2RGB) #PIL uses RGB and OpenCV uses BGR
base_temp = Image.fromarray(base_temp) #Convert to PIL Image
foreground_temp = cv2.cvtColor(cv2.convertScaleAbs(self.last_img), cv2.COLOR_BGR2RGB)
foreground_temp = Image.fromarray(foreground_temp)
base_temp.paste(foreground_temp, offset)
I'm using python3.5 and and OpenCV3.4 on Windows 10, if that's any help.
I'd like to avoid any solutions that require saving the cv2 images and then reloading them in another module to convert them but if it's unavoidable that's okay too. Any help would be appreciated!
If you check the type of base_temp, you will see it is float64 and that is going to cause you problems when you try to save it as a JPEG which expects unsigned 8-bit values.
So the solution is to create your base_temp image with the correct type:
base_temp = np.zeros((1000,1000,3), dtype=np.uint8)
The complete code and result look like this:
import cv2
import numpy as np
from PIL import Image
# Make black background - not square, so it shows up problems with swapped dimensions
base_temp=np.zeros((768,1024,3),dtype=np.uint8)
foreground_temp=cv2.imread('monitor.png')
# Paste with different x and y offsets so it is clear when indices are swapped
offset_y=80
offset_x=40
base_temp[offset_y:offset_y+foreground_temp.shape[0], offset_x:offset_x+foreground_temp.shape[1]] = foreground_temp
Image.fromarray(base_temp).save('result.png')
Traceback (most recent call last):
File "demo.py", line 132, in
`result = find_strawberry(image)`
File "demo.py", line 63, in find_strawberry
`image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)`
cv2.error: OpenCV(3.4.2) /Users/travis/build/skvark/opencv-python/opencv/modules/imgproc/src/color.hpp:253: error: (-215:Assertion failed) VScn::contains(scn) && VDcn::contains(dcn) && VDepth::contains(depth) in function 'CvtHelper'
I personally have spent a lot of time on this question, hence thought relevant to post it on Stackoverflow.
Question taken from: llSourcell/Object_Detection_demo_LIVE
Even I had the same problem, and the solution was quiet easy. Remember 1 thing, if the RGB values of your image lie in the range of 0-255, make sure the values are not of data type 'float'. As OpenCV considers float only when values range from 0-1. If it finds a float value larger than 1 it clips off the value thinking floats only exists between 0-1. Hence such errors generated. So convert the data type to uint8 if values are from 0-255.
image = image.astype('uint8')
Check this Kaggle Kernel to learn more about it
Just in case if anyone is still having the same error even after applying the above fix then do check the depth of your image i.e. Check whether the image is grayscale or colored since cv2.COLOR_BGR2GRAY cannot convert images that are already grayscale and thus throws up this error.
Well I was doing the Epipolar Geometry (find the link below) and I had this issue. I solved this error by doing one of the two methods:
First method - keeping the original colors:
A. I load the image with its original color (in my case it was RGB) by deleting the zero parameter from cv2.imread.
img1 = cv2.imread('image.jpg')
B. You might need to edit the shape of the image since it is RGB
r, c,_ = img1.shape
C. Comment the conversion
# img1 = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)
The second method - converting into grayscale image:
A. I load the image in BGR by adding the zero parameter into cv2.imread.
img1 = cv2.imread('image.jpg',0)
B. You might need to edit the shape of the image since it is BGR
r, c = img1.shape
C. Now you can convert the image into grayscale image
img1 = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)
If the two methods do not work for you, you might need to check the links below they might have answer your question:
https://github.com/aleju/imgaug/issues/157
https://github.com/llSourcell/Object_Detection_demo_LIVE/issues/6
Epipolar Geometry
https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_calib3d/py_epipolar_geometry/py_epipolar_geometry.html
get the same error while using trackbar in opencv but this method resolved it:
img = np.full((512,512,3), 12, np.uint8)
where img is your image
I'm trying to segment a grayscale picture generated from field measurements, that is why it is not a conventional 3-channel picture.
I have tried this piece of code:
import cv2 #this is the openCV library
import numpy as np
# some code to generate img
ret,thresh = cv2.threshold(img ,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
And it spits out this error:
cv2.error: ..\..\..\modules\imgproc\src\thresh.cpp:719: error: (-215) src.type() == CV_8UC1 in function cv::threshold
I have no idea on how to solve this since the usage seems to be pretty straight forward, so any idea is welcome.
The error is due to the following assert statement CV_Assert( src.type() == CV_8UC1 ); in thresh.cpp, meaning your input image is not of type CV_8UC1.
So make sure that your generated input image img is in fact CV_8UC1 (one channel 8-bit image).
So indeed the problem is the image type, since it contains double values thay need to be normalized to 0 ~ 255.
in my case 1000 is the maximum value possible
img = cv2.convertScaleAbs(img / 1000.0 * 255)
This worked for me.
i am writing a face dection program in opencv. And this is the error code below:
result = img[rects[0]:rects[1], rects[2]:rects[3]]
result = cv2.resize(result, (100,100))
img is our original picture and the first step is croping out our rigion of interest into result.
The second step is resize to 100*100 pixels.
the error is:
result = cv2.resize(result, (100,100))
error: ..\..\..\src\opencv\modules\imgproc\src\imgwarp.cpp:1725: error: (-215) ssize.area() > 0
Hope someone can help me. Thanks a lot.
Had the same error in python ,found that image was empty so check whether imread worked or not by using imshow or checking it for NULL then use cv2.resize .