Applying effect on all pictures in folder (python) - python

I have a simple code, that applies effect on one of my pictures:
from matplotlib import pyplot as plt
import os
import cv2
path_in=os.path.join("C:/Users/Desktop/Images","glass.jpg")
img = cv2.imread(path_in, cv2.IMREAD_COLOR)
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()
but problem is, that I want to apply this to all images in my folder and I don't know their names.
So I understand that I need to create loop with the list of my images in folder, but I have tried this and it didn't work
path_in=os.path.join("C:/Users/Desktop/Images")
list = os.listdir(path_in)
for img in list:
img = cv2.imread(path_in, cv2.IMREAD_COLOR)
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
io.imsave("C:/Users/Desktop/Images_new", image_converted)
plt.imshow(img)
plt.show()
I would be very glad if someone could tell me, what I am doing wrong. Thank you

You are already on the right track. There are just a few minor issues with your code:
First, define the path_in inside the loop and join your folder path with the image name. Second, never use keywords from the python language as variable names. The name list is a python keyword.
I don't know the functions imsave, imshow and show in details, so I'm not sure if they should be inside of the loop. I guess, but there you may need to just test it. Also, for imsave, it may be that you need to set a path for each image. In that case you could do it like io.imsave("C:/Users/Desktop/Images_new/{}".format(img), image_converted).
path_folder = "C:/Users/Desktop/Images"
img_list = os.listdir(path_in)
for img in img_list:
path_in = os.path.join(path_folder, img)
img = cv2.imread(path_in, cv2.IMREAD_COLOR)
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
io.imsave("C:/Users/Desktop/Images_new", image_converted)
plt.imshow(img)
plt.show()
No 100% guarantee it works exaclty as is. Let me know if you get an error.

path_folder = "C:/Users/Desktop/Images"
img_list = os.listdir(path_in)
for img in img_list:
path_in=os.path.join("C:/Users/Desktop/Images",img)
path_out = os.path.join("C:/Users/Desktop/Images_new", img)
img = cv2.imread(path_in, cv2.IMREAD_COLOR)
image_converted = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
io.imsave(path_out, image_converted, format = 'jpg')
plt.imshow(image_converted)
plt.show()

Related

python OCR recognize image into text

seems resolution of image effect the output is success or not
usually the image's resolution/quality from production line is like test image 1, instead of change camera quality, is there any way to make success rate higher? like improve code make simple AI to help detect or something? I need a hand thanks.
the demo .py code I found from tutorial
from PIL import Image
import pytesseract
img = Image.open('new_003.png')
text = pytesseract.image_to_string(img, lang='eng')
print("size")
print(img.size)
print(text)
(pic) test image 1: https://ibb.co/VLsM9LL
size
(122, 119)
# the output is:
R carac7
(pic) test image 2: https://ibb.co/XyRcf45
size
(329, 249)
# the output is:
R1 oun,
2A
R ca7ac2
(pic) test image 3: https://ibb.co/fNtDRc7
this one just for test but is the only one 100% correct
size
(640, 640)
# the output is:
BREAKING THE STATUE
i have always known
i just didn't understand
the inner conflictions
arresting our hands
gravitating close enough
expansive distamce between
i couldn't give you more
but i meant everything
when the day comes
you find your heart
wants something more
than a viece and a part
your life will change
like astatue set free
to walk among us
to created estiny
we didn't break any rules
we didn't make mistakes
making beauty in loving
making lovine for days
SHILOW
I tried to find out/proof the solution can only be the image resolution or there can be other alternative way to solve this issue
I try Dilation and Erosion to image, hoped can get more clear image for OCR recognize like link demo pic https://ibb.co/3pDgDnF
import cv2
import numpy as np
import matplotlib.pyplot as plt
import glob
from IPython.display import clear_output
def show_img(img, bigger=False):
if bigger:
plt.figure(figsize=(15,15))
image_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(image_rgb)
plt.show()
def sharpen(img, sigma=100):
# sigma = 5、15、25
blur_img = cv2.GaussianBlur(img, (0, 0), sigma)
usm = cv2.addWeighted(img, 1.5, blur_img, -0.5, 0)
return usm
def img_processing(img):
# do something here
img = sharpen(img)
return img
img = cv2.imread("/home/joy/桌面/all_pic_OCR/simple_pic/03.png")
cv2.imshow('03', img) # Original image
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (11, 11))
img = cv2.dilate(img, kernel) # tried Dilation
cv2.imshow('image_after_Dilation', img) # image after Dilation
img = cv2.erode(img, kernel) # tried Erosion
cv2.imshow('then_Erosion', img) # image after Erosion
cv2.waitKey(0)
cv2.destroyAllWindows()
result: https://ibb.co/TbZjg3d
so still trying to achieve python OCR recognize image into text with 99.9999% correct

Python PyTesseract Acuracy Improvement

I know this has been asked before, and I have been trying several different methods and changing things, but cannot figure out how to get this to work. I have a bunch of pages where this works perfectly. This is clear text perfectly laid out. But for some reason, on one of the sheets it is messing up and reading completely wrong info. Below I have attached my code, output, and the image.
import pytesseract
import cv2
import numpy as np
img = cv2.imread('page_3.jpg')
img = cv2.resize(img, None, fx=2, fy=2)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernel = np.ones((1, 1), np.uint8)
cv2.imwrite('thresh.png', img)
for psm in range(6, 13 + 1):
config = '--oem 3 --psm %d' % psm
txt = pytesseract.image_to_string(img, config=config, lang='eng')
print('psm ', psm, ':', txt)
Here is the photo:
And then here is the output. It works perfectly until the end for some reason. All of the outputs (psm 6, 11, and 12) are reading the exact same. Any help is appreciated.
1885-1015
1886-1280
1956-0044
2087-0047
2087-0155
2087-1433
2221-0093L
2221-0093R
2331-4628R
2992-/114R
29593-0007R
Your image does not require any pre-processing at all. It is already perfect and structured. So try not to resize the image before passing it to tesseract. Resizing is not needed in your case.
Hope this helps.

how to save an image in python variable and then change it to grayscale?

I need to do image processing for barcode. I know that I can save a picture and then load it in grayscale color_mode, but I dont want to load an image, instead I want to change the color of image into grayscale without saving or without having another image.
imag=Image.open('barcode.png')
w, h = imag.size
region = imag.crop((0, 20, w, h-150))
region.save("regions.png") #I dont want to save this image
img=image.load_img("regions.png",color_mode="grayscale") #I want to do this work in a variable i.e. changing the color of image into grayscale without having a need of loading an image
Looks like you are using pillow.
In pillow, you can do Image.convert()
To convert to grayscale, do Image.convert('LA')
The mode LA is combination of "8-bit pixels, black and white" and "alpha channel". See here for more about different available modes.
Replace you code with the following:
imag = Image.open('barcode.png')
w, h = imag.size
region = imag.crop((0, 20, w, h-150))
img = region.convert('LA')
If you can use OpenCV, cv2.cvtColor works like below:
import numpy as np
import cv2
img_filepath = "your_image.PNG"
img = cv2.imread(img_filepath)
grayed = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("grayed", grayed)
cv2.waitKey(0)
cv2.destroyAllWindows()

Want to append colored images to a list and convert that list to grayscale using OpenCV

So basically I'm trying to convert a set of RGB images to grayscale using cv2.cvtColor and python is throwing the following error:
Traceback (most recent call last):
File "MCG.py", line 53, in
gray = cv2.cvtColor(data, cv2.COLOR_BGR2GRAY)
TypeError: src is not a numpy array, neither a scalar.
This here is the code:
import numpy as np
import cv2
import dlib
import sys
import skimage
from PIL import Image
import os
import glob
folderpath = sys.argv[1]
cascPath = sys.argv[2]
imageformat = ".tif"
path = folderpath
imfilelist = [os.path.join(path,f) for f in os.listdir(path) if f.endswith(imageformat)]
data = []
for IMG in imfilelist:
print IMG
image = cv2.imread(IMG)
data.append(image)
cv2.imshow('Image', image)
cv2.waitKey(0)
faceCascade = cv2.CascadeClassifier(cascPath)
predictor = dlib.shape_predictor(PREDICTOR_PATH)
gray = cv2.cvtColor(data, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.05,
minNeighbors=5,
minSize=(100,100)
)
As you can see, I'm trying to append all these images to a list, which will then be converted using the cv2.cvtColor function. However, that error is thrown. What am I doing wrong? Thank you.
P.S if anyone is wondering why I imported modules that don't seem to be used in this code, this code is just a segment of the whole thing and all of those modules have are being utilized in one way or the other.
If you read the cv2.cvtColor documentation, you can see that the first parameter is the Src 8-bit single channel image. However, in your case you are giving an entire list of images.
So change the code as
gray = []
for j in range(0,len(data)):
gray.append(cv2.cvtColor(np.array(data[j]), cv2.COLOR_BGR2GRAY))
I guess this should work.
You are collecting the images into a list with
data = []
for IMG in imfilelist:
...
data.append(image)
....
and then trying to convert the list with
gray = cv2.cvtColor(data, cv2.COLOR_BGR2GRAY)
This is why you are getting the error - the error is telling you that data is not an image (numpy array) but is a list. You need to convert one image at a time with cv2.cvtColor().
You could try
gray = []
for img in data:
gray.append(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))
This would give you a list of greyscaled images, which is what I think you want to do.

How can i read input only a part of the image without creating another image?

import cv2
fname = '1.png'
img=cv2.imread(fname, 0)
print (img)//the outcome is an array of values from 0 to 255 (grayscale)
ret, thresh = cv2.threshold(img, 254, 255, cv2.THRESH_BINARY)
thresh = cv2.bitwise_not(thresh)
nums, labels = cv2.connectedComponents(thresh, None, 4, cv2.CV_32S)
dst = cv2.convertScaleAbs(255.0*labels/nums)
cv2.imwrite(dest_dir+"output.png", dst)
that code works just fine, so i moved on to adjusting my code so it can take a portion of the image not the entire image:
from PIL import Image
img = Image.open(fname)
img2 = img.crop((int(xmin), int(yMin),int(xMax), int(yMax))
xmin ymin xmax ymax simply being the top left bottom right coordinates of the box.
then i did img = cv2.imread(img2) to continue as the previous code but got an error, i printed img2 and got <PIL.Image.Image image mode=RGB size=54x10 at 0x7F4D283AFB70> how can i adjust it to be able to input that crop or image portion instead of fname in my code above, and kindly note i don't want to save img2 as an image and carry on from there because i need to work on the main image.
try cv2.imshow() instead of printing it. In order to see an image you cropped, you need to use cv2 function. here is a sample code:
import numpy as np
import cv2
# Load an color image in grayscale
img = cv2.imread('messi5.jpg',0)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
The simple answer is NO you cannot.
Open up your terminal /IDE and type in help(cv2.imread).
It clearly states that The function imread loads an image from the specified file and returns it. So in order to use cv2.imread() you must pass it in as a file not an image.
Your best bet would be to save your cropped image as a file and then read it.

Categories