adaptive thresholding ---ValueError: too many values to unpack - python

I'm pretty amateur at image processing. I could successfully do normal thresholding but however I'm facing an error in Adaptive Thresholding.
Here is my code:
import cv2
import numpy as np
img = cv2.imread("vehicle004.jpg")
img = cv2.medianBlur(img,5)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
_,th2=cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)
cv2.imshow("window2",th2)
cv2.waitKey(0)
cv2.destroyAllWindows()
Error Message:
line 7, in <module>
_,th2 = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)
ValueError: too many values to unpack
Any help is appreciated.

As per the documentation, the cv2.adaptiveThreshold() returns only 1 value that is the threshold image and in this case you are trying to receive 2 values from that method, that is why ValueError: too many values to unpack error is raised.
After fixing the issue the code may look like:
import cv2
import numpy as np
img = cv2.imread("vehicle004.jpg")
img = cv2.medianBlur(img,5)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
th2=cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)
cv2.imshow("window2",th2)
cv2.waitKey(0)
cv2.destroyAllWindows()

Related

OpenCV: Hough Circles, trouble detecting object

I am a complete beginner when it comes to OpenCV, I have no clue where to start when trying to detect circles of a certain size, below is my current code (not much) along with the image I am trying to detect, if anyone could help me or give me some advice it would be much appreciated, (i have converted image to grayscale and added gaussian blur so it is easier to detect) Thanks!
Image
import cv2
import numpy as np
test = cv2.imread('test.jpg')
gray_img = cv2.cvtColor(test, cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(gray_img, 5)
cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
cv2.imshow("HoughCirlces", test)
cv2.waitKey()
cv2.destroyAllWindows()
great work, you're almost there, all you have to do now is actually apply the CHT. The function you are looking for is cv2.HoughCircles(). You need to pass the image, in your case you can use either img or cimg and some parameters that might require tuning. Here is some template code
import cv2
import numpy as np
test = cv2.imread('test.jpg')
gray_img = cv2.cvtColor(test, cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(gray_img, 5)
cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(img,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("HoughCirlces", test)
cv2.waitKey()
cv2.destroyAllWindows()
You can also take a look at the documentation and tutorial. I'll link them below.
Tutorial: https://docs.opencv.org/4.x/da/d53/tutorial_py_houghcircles.html
Docs: https://docs.opencv.org/4.x/dd/d1a/group__imgproc__feature.html#ga47849c3be0d0406ad3ca45db65a25d2d

Pytesseract converting to wrong strings

I'm currently using pytesseract and cv2 to try to read this Health Bar.
The only problem is that when I try to convert it to a string using pytesseract.image_to_string(img), it recognizes this line before the number 1 as 1 itself, so the returned value is : 11189/10180
Any thoughts on how can I work around this problem? Thanks a lot in advance!
If you apply OTSU's threshold:
The OCR result is:
| 1189 / 10180
if you don't want | and /, you can use isalnum() but this time result will be:
118910180
Code:
import cv2
import pytesseract
# Load the image
img = cv2.imread("glwMK.png")
# Convert to the gray-scale
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Threshold
thr = cv2.threshold(gry, 120, 255, cv2.THRESH_OTSU)[1]
# OCR
print(pytesseract.image_to_string(thr))
# Display
cv2.imshow("", thr)
cv2.waitKey(0)

Pytesseract image_to_string empty output

I have this image that was cropped from another image and I want to give this image as an input to image_to_string method:
import pytesseract
import cv2
num_plate = cv2.imread('E:\Images\car_plate222.jpeg' , cv2.IMREAD_GRAYSCALE)
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
cv2.dilate(num_plate, (15, 15), num_plate)
pytesseract.image_to_string(num_plate)
Here's the photo:
Car Plate:
I used dilation for better performance, but it doesn't give me desired output (Sometimes gives me empty string and sometimes gives me weird output)
Does anybody know what's wrong?
You must threshold the image before passing it to pytesseract. That increases the accuracy.
Here is a sample:
import cv2
import numpy as np
import pytesseract
from PIL import Image
# Grayscale image
img = Image.open('E:\\WorkDir\\KAVSEE\\Python\\test.jpg').convert('L')
ret,img = cv2.threshold(np.array(img), 125, 255, cv2.THRESH_BINARY)
# Older versions of pytesseract need a pillow image
# Convert back if needed
img = Image.fromarray(img.astype(np.uint8))
print(pytesseract.image_to_string(img))
Hope this helps :)

Python OCR issues with Pytesseract

I am trying to read some characters that come out on the screen, but none of my attempts is successful. Example image here
And here is my code:
import pytesseract as tess
tess.pytesseract.tesseract_cmd = r'C:\Users\myuser\AppData\Local\Tesseract-OCR\tesseract.exe'
from PIL import Image
img = Image.open(r'E:\images\numbers.PNG')
text = tess.image_to_string(img)
print(text)
The "garbage" output that displays is:
C NCES IC DICIIED)
CK STOO TEED
#©O®D#O#O#O#O®
I suppose this is happening because of the color of the numbers, and the different background image they could appear on.
Unfortunately I do not know how to proceed further and how to get it working.
Can you please help? Your assistance is much appreciated!
Thanks!
I don't have Tesseract installed right now but try with the result of this code:
import cv2
img = cv2.imread('img.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 3, 6)
cv2.imshow('threshold', thresh)
cv2.waitKey(0)
You can fine tune it to achieve your result.

OpenCV: Error with adaptive thresholding (Error -215)

I am trying to do adaptive thresholding after applying Sobel filtering on an image, as seen in the code below:
import numpy as np
import matplotlib.pyplot as plt
import cv2
image = cv2.imread("train.jpg")
img = np.array(image, dtype=np.uint8)
#convert to greyscale
img_grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#remove noise
img_smooth = cv2.GaussianBlur(img_grey, (13,13), 0)
sobely = cv2.Sobel(img_smooth,cv2.CV_64F,0,1,ksize=9)
thres = cv2.adaptiveThreshold(sobely, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 73, 2)
However, when I try to do adaptive thresholding, I get the following error:
cv2.error: OpenCV(4.1.0) /Users/travis/build/skvark/opencv-
python/opencv/modules/imgproc/src/thresh.cpp:1627: error: (-215:Assertion
failed) src.type() == CV_8UC1 in function 'adaptiveThreshold'
I have read that this error occurs if your image is not greyscale, however, I converted my image to greyscale at the start of the code. I am not sure why I am getting this error. Any insights are appreciated.
What you read is correct, that error actually means that your Mat is not a gray-scale image.
That happens because Sobel is changing the data to cv2.CV_64F (see the second parameter in the documentation here).
So after Sobel you need to convert the image to a gray-scale, you can do that with convertScaleAbs and after that pass it's output to adaptiveThreshold

Categories

Resources