Why i have this issue with cv2.findContours function? - python

Traceback (most recent call last):
File "C:/Users/michail.gakas/Desktop/python scripts/counters.1py.py", line 10, in
imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
error: C:\builds\master_PackSlaveAddon-win64-vc12-static\opencv\modules\imgproc\src\color.cpp:7456: error: (-215) scn == 3 || scn == 4 in function cv::ipp_cvtColor
My code:
import numpy as np
import cv2
img = cv2.imread('star.jpg',0)
imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
I am using python 2.7 CV3 but i had CV2 installed before

I don't have OpenCV with me right now but from what I see you did
img = cv2.imread("star.jpg", 0)
but what you probably wanted to do is open it in color as:
img = cv2.imread("star.jpg", 1)
or open it "unchanged" as:
img = cv2.imread("star.jpg", -1)
What you did is you opened an image in grayscale mode and then tried to convert it to grayscale. That error actually states that assert didn't find an image with 3 or 4 channels and BGR2GRAYSCALE goes from a color jpg image (3 channels) or a color png image (4 channels, 1 for alpha sometimes) to a 1 channel grayscale image. Alpha channel is discarded in this function. Pls make your life easier and use the official flags cv2 offers for easier code readability.
cv2.IMREAD_UNCHANGED (<0) loads the image as is (including the alpha channel if present)
cv2.IMREAD_GRAYSCALE ( 0) loads the image as an intensity one
cv2.IMREAD_COLOR (>0) loads the image in the RGB format

Related

how to binaries the image, assign the zeros and one into 2D image by a threshold point using python and convert it to RGB?

I have written the following code in MATLAB and want to convert it into python code. How can we find the MatLab instruction into python:
MatLab Code:
path = 'C:\Users\hp\Desktop\output\result_0.png';
img = imread(path);
size(img)
img = rgb2gray(img);
size(img)
m = mean(img(:));
img = img>m;
RGB = cat(3, img, img, img);
size(RGB)
Code in Python:
path = r"C:\\Users\\hp\\Desktop\\output\\result_0.png"
img = cv2.imread(path)
print(img.shape)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
result = gray.flatten()
m = statistics.mean(result)
print(m)
gray = gray>m
img = gray.astype(int)
print(img)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
how to correct the python code, so that it works as MatLab code?
I am getting the error after running the python code:
Traceback (most recent call last):
File "C:/pytorch-GaitGAN-master/src/test2.py", line 24, in <module>
cv2.imshow('image',img)
cv2.error: OpenCV(4.0.0) c:\projects\opencv-python\opencv\modules\imgproc\src\color.hpp:261: error: (-2:Unspecified error) in function '__cdecl cv::CvtHelper<struct cv::Set<1,-1,-1>,struct cv::Set<3,4,-1>,struct cv::Set<0,2,5>,2>::CvtHelper(const class cv::_InputArray &,const class cv::_OutputArray &,int)'
> Unsupported depth of input image:
> 'VDepth::contains(depth)'
> where
> 'depth' is 4 (CV_32S)
the following code, I was required:
import cv2
import numpy as np
path = r"C:\\Users\\hp\\Desktop\\output\\result_0.png"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray[gray<np.mean(gray)] = 0.
gray[gray>=np.mean(gray)] = 255.
print(gray.shape)
img = np.stack((gray,)*3, axis=-1)
print(img.shape)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Based on your Matlab code, I think you want to threshold you image based on the mean value m. You can use cv2.threshold to do this.
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
result = gray.flatten()
m = statistics.mean(result)
gray_thres = cv2.threshold(gray,m,255,cv2.THRESH_BINARY)
You may need to change the value 255 to the max value in your image. More info here.

newbie - attempting object tracking / locating in opencv python, problems with findContours()

I'm attempting to locate a rectangular object by its color, and then find the coordinates of the center of the object, or the borders, I"m not picky about which.
I've been successful in isolating the color and creating a mask, but the findContours function is not working and i think it's because i've not successfully provided a proper bimodal image to findContours.
%matplotlib inline
import matplotlib.image as mpimg
from matplotlib import pyplot as plt
import cv2
import numpy as np
red_image = mpimg.imread('/vagrant/notebooks/red_thing.jpg')
hsv = cv2.cvtColor(red_image, cv2.COLOR_BGR2HSV)
lower_red = np.array([30,150,50])
upper_red = np.array([255,255,180])
mask = cv2.inRange(hsv, lower_red, upper_red)
res = cv2.bitwise_and(red_image,red_image, mask= mask)
kernel = np.ones((20,20),np.uint8)
ret,thresh1 = cv2.threshold(res,60,255,cv2.THRESH_BINARY)
# perform 'open' operation to homogenize object
opened = cv2.morphologyEx(thresh1, cv2.MORPH_OPEN, kernel)
image, contours, hierarchy = cv2.findContours(opened,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
The last line produces the following error, I can't figure out how to resolve this.
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-130-06cc5691b64a> in <module>()
----> 1 image, contours, hierarchy = cv2.findContours(opened,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
error: /home/vagrant/opencv/modules/imgproc/src/contours.cpp:199: error: (-210) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function cvStartFindContours_Impl
i was able to fix the error with a conversion to gray, like this: gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)

PIL - TypeError: src is not a numpy array, neither a scalar

from PIL import Image
import pytesseract
import argparse
import cv2
import os
image = Image.open("C:/Users/NB/Desktop/Scan/Arti818.jpg")
#image = "C:/Users/NB/Desktop/Scan/Arti818.jpg"
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# check to see if we should apply thresholding to preprocess the
# image
gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# make a check to see if median blurring should be done to remove
# noise
# write the grayscale image to disk as a temporary file so we can
# apply OCR to it
filename = "{}.png".format(os.getpid())
cv2.imwrite(filename, gray)
# load the image as a PIL/Pillow image, apply OCR, and then delete
# the temporary file
text = pytesseract.image_to_string(Image.open(filename))
os.remove(filename)
print(text)
# show the output images
cv2.imshow("Image", image)
cv2.imshow("Output", gray)
cv2.waitKey(0)
This is my code and I am getting following error:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
TypeError: src is not a numpy array, neither a scalar
Read the docs. It clearly says:
PIL.Image.open(fp, mode='r')
Opens and identifies the given image file.
Returns: An Image object.
The object returned is of Image type, not a numpy.ndarray. If you want an array, convert image to one:
gray = cv2.cvtColor(np.asarray(image), cv2.COLOR_BGR2GRAY)

Opencv Pythonprogram

I am trying opencv with python now.
What mean this error?
OpenCV Error: Assertion failed (m.dims >= 2) in Mat, file /build/opencv-ISmtkH/opencv-2.4.9.1+dfsg/modules/core/src/matrix.cpp, line 269
Traceback (most recent call last):
File "sabun5.py", line 16, in <module>
img_m = cv2.threshold(img_df, 50, 255, cv2.THRESH_BINARY)[1]
cv2.error: /build/opencv-ISmtkH/opencv-2.4.9.1+dfsg/modules/core/src/matrix.cpp:269: error: (-215) m.dims >= 2 in function Mat
You can see in the OpenCV documentation, that the threshold function just allow single-channel images.
If your image is a color one, it won't work. If it's grayscale but you are loading it with imread, it might be possible that OpenCV load it as a 3-channel one. You can add the flag to load it as a single-channel with CV_8UC1 (supposing it is an 8 bit unsigned one, which is the more common for a grayscale image).
For example:
img_df = cv2.imread("image/path", cv2.CV_8UC1)
you have to convert the image into grayscale before thresholding your image has more then two dimentions i.e (height,width,color-channel) gray scale image has only two dimention(height,width)
it might help
import cv2
img = cv.imread('x.png',0)
# where 0 converts the image in grayscale or gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_m = cv2.threshold(img, 50, 255, cv2.THRESH_BINARY)[1]
cv2.waitKey(0)

OpenCV findContours in python

I am working in python on openCV 3.0. In order to find the largest white pixel region, first of all thresholded gray image to binary image.
import cv2
import numpy as np
img = cv2.imread('graimage.png')
img = cv2.resize(img,(400,500))
gray = img.copy()
(thresh, im_bw) = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY )
derp,contours,hierarchy = cv2.findContours(im_bw,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
cnts = max(cnts, key=cv2.contourArea)
But it shows error as follows.
cv2.error: ..../opencv/modules/imgproc/src/contours.cpp:198: error: (-210) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function cvStartFindContours.
It looks like this was answered in the comments, but just to mark the question as answered:
CV_8UC1 means 8-bit pixels, unsigned, and only one channel, so grayscale. It looks like you're reading it in with 3 color channels, or CV_8UC3. You can check the image type by printing img.dtype and img.shape. The dtype should be uint8, and the shape should be (#, #), indicating two dimensions. I'm guessing you'll see that shape prints (#, #, 3) for your image as-is, indicating three color channels.
As #user3515225 said, you can fix that by reading the image in as grayscale using cv2.imread('img.png', cv2.IMREAD_GRAYSCALE). That assumes you have no use for color anywhere else, though. If you want a separate grayscale copy of the image, then replace gray = img.copy() with gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) instead.

Categories

Resources