# organizing imports
import cv2
import numpy as np
import os
from PIL import ImageTk, Image
from os import listdir
from PIL import Image as PImage
# path to input image is specified and
# image is loaded with imread command
imagesdog = np.array([])
new_array = np.array([])
rootdirectory2 = os.listdir('alldata/data2/')
## Saves all images in directory to array from RGB values and resizes
for allimages in rootdirectory2:
image = Image.open('alldata/data2/' + allimages)
imagesave = np.asarray(image) ## Filters the image
smaller = cv2.resize(imagesave, (500, 500))
data = Image.fromarray(smaller)
IMG_SIZE = 500
xyz = cv2.resize(smaller, (IMG_SIZE, IMG_SIZE))
new_array = np.append(new_array, xyz)
## resized and appended, need to be added as a list
#cv2.imshow('Filtered', new_array[3])
for elements in new_array:
print(elements)
image1 = cv2.imread('alldata/data/image3.jpeg')
image1 = cv2.resize(image1, (500,500))
# cv2.cvtColor is applied over the
# image input with applied parameters
# to convert the image in grayscale
img = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
# applying different thresholding
# techniques on the input image
# all pixels value above 120 will
# be set to 255
ret, thresh1 = cv2.threshold(img, 120, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img, 120, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img, 120, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img, 120, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img, 120, 255, cv2.THRESH_TOZERO_INV)
# the window showing output images
# with the corresponding thresholding
# techniques applied to the input images
print(len(new_array))
cv2.imshow('Binary Threshold', new_array[499])
cv2.imshow('Binary Threshold Inverted', thresh2)
cv2.imshow('Truncated Threshold', thresh3)
cv2.imshow('Set to 0', thresh4)
cv2.imshow('Set to 0 Inverted', thresh5)
# De-allocate any associated memory usage
if cv2.waitKey(0) & 0xff == 27:
cv2.destroyAllWindows()
I am working on a project where I intend to load in images, reduce them to their RGB values in a list and resize them, then add them to an array later to be filtered. Then reload them later on and be filtered.
Right know, I am struggling to get images separated. I have reduced to this for getting this accomplished. I keep getting an output of all the RGB values separated into 40600 elements and can't pull them out after initial appending.
Any help figuring out how I can get them to be added in [] and separated while being appending the resized versions, and returning the separated images in a multidimensional array?
Loading in using the same libraries, I couldn't resize them correctly. I reduced down to this method.
Related
Here is the code that i'm trying to modify. To read and save all the images at once in one folder, however I got error when I tried to save it
import cv2
import glob
import numpy as np
#empty lists
image_list=[]
images = []
for img in glob.glob(r"C:\Users\user\Documents\Dataset\Test\Abnormal_Resize\Abnormal_Crop\*.png"):
n= cv2.imread(img)
images.append(n)
print (img)
#limit list to 236 elements
image_list = image_list[:100]
#Resizing the image for compatibility
for img in image_list:
image = cv2.resize(image, (500, 600))
#The initial processing of the image
#image = cv2.medianBlur(image, 3)
image_bw = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#The declaration of CLAHE
#clipLimit -> Threshold for contrast limiting
clahe = cv2.createCLAHE(clipLimit = 5)
final_img = clahe.apply(image_bw)
cv2.imwrite(path+r"C:\Users\user\Documents\Dataset\Test\Abnormal_Resize\Abnormal_Crop\Abnormal_Cntrst\contrast_"+str(i)+".png", final_img)
It seems like there are multiple issues with this code.
i is not defined.
images list has all the images appended and while processing you are making use of the empty list variable image_list
You are probably looking for a solution like this.
import cv2
import glob
import numpy as np
input_path = r"<your_input_folder_path>/*.png"
# make sure below folder already exists
out_path = '<your_output_folder_path>/'
image_paths = list(glob.glob(input_path))
for i, img in enumerate(image_paths):
image = cv2.imread(img)
image = cv2.resize(image, (500, 600))
#The initial processing of the image
#image = cv2.medianBlur(image, 3)
image_bw = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#The declaration of CLAHE
#clipLimit -> Threshold for contrast limiting
clahe = cv2.createCLAHE(clipLimit = 5)
final_img = clahe.apply(image_bw)
cv2.imwrite(out_path + f'{str(i)}.png', final_img)
I have an image that looks like this:
And this is the processed image
I have tried pretty much everything. I processed the image like this:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #Converting to GrayScale
(h, w) = gray.shape[:2]
gray = cv2.resize(gray, (w*2, h*2))
thresh = cv2.threshold(gray, 150, 255.0, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
gray = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, rectKernel)
blur = cv2.GaussianBlur(gray,(1,1),cv2.BORDER_DEFAULT)
text = pytesseract.image_to_string(blur, config="--oem 1 --psm 6")
But Tesseract doesnt print out anything. I am using this version of tesseract
5.0.0-alpha.20201127
How do I improve it's performance? Its highly unreliable.
Edit:
The answer below did a wonderful job on the said image.
But when I apply this technique to image like this one I get wrong output
Why is that? They seem roughly the same.
The problem is characters are not in center of the image.
Sometimes, tesseract have difficulty recognizing the characters or digit if they are not on the center.
Therefore my suggestion is:
Center the characters
Up-sample and convert to gray-scale
Centering the characters:
cv2.copyMakeBorder(img, 50, 50, 50, 50, cv2.BORDER_CONSTANT, value=[255])
50 is just a padding variable, you can set to any other value.
The background turns blue because of the value. OpenCV read the image in BGR fashion. giving 255 as an input is same as [255, 0, 0] which is display blue channel, but not green and red respectively.
You can try with other values. For me it won't matter, since I'll convert it to gray-scale on the next step.
Up-sampling and converting to gray-scale:
The same steps you have done. The first three-line of your code.
Now when you read:
MEHVISH MUQADDAS
Code:
import cv2
import pytesseract
# Load the image
img = cv2.imread("onf0D.jpg")
# Center the image
img = cv2.copyMakeBorder(img, 50, 50, 50, 50, cv2.BORDER_CONSTANT, value=[255])
# Up-sample
img = cv2.resize(img, (0, 0), fx=2, fy=2)
# Convert to gray-scale
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# OCR
txt = pytesseract.image_to_string(gry, config="--psm 6")
print(txt)
Read more tesseract-improve-quality.
You don't need to do threshold, GaussianBlur or morphologyEx.
The reasons are:
Simple-Threshold is used to get the features of the image. Input images' features are already available.
You don't have to smooth the image, there is no illumination effect on the image.
You don't need to do segmentation, since background is plain-white.
Update-1
The second image requires pre-processing. However, applying simple-threshold won't work on this image. You need to remove the background using a binary mask, then you can apply OCR.
Result of the binary-mask:
Now, if you apply OCR:
IRUM FEROZ
Code:
import cv2
import numpy as np
import pytesseract
# Load the image
img = cv2.imread("jCMft.jpg")
# Center the image
img = cv2.copyMakeBorder(img, 50, 50, 50, 50, cv2.BORDER_CONSTANT, value=[255])
# Up-sample
img = cv2.resize(img, (0, 0), fx=2, fy=2)
# Convert to HSV color-space
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# Adaptive-Threshold
msk = cv2.inRange(hsv, np.array([0, 0, 0]), np.array([179, 255, 130]))
# OCR
txt = pytesseract.image_to_string(msk, config="--psm 6")
print(txt)
Q:How do I find the lower and upper bounds of the cv2.inRange method?
A: You can use the following script.
Q: What did you change in the second image?
A: First I converted image to the HSV format, instead of gray-scale. The reason is I wanted remove the background. If you experiment with adaptiveThreshold you will see there are a lot of artifacts on the background limits the tesseract recognition. Then I used cv2.inRange to get a binary mask. Feeding binary-mask to the input gave me the desired result.
This is the source image I am working with:
I am using this github repository (the file I'm using is tools/test_lanenet.py) to do binary lane segmentation. now I get this image:
The second image is actually an image resulted from this command:
# this line results in an array with the shape of (512, 256). this is just a hypothetical line of code. what I really care is the line which saves the image with matplotlib library.
binary_seg_image = lane_segmenter.binary_segment()
# this line saves the image
plt.imsave('binary_image_plt.png', binary_seg_image[0] * 255, cmap='gray')
First I have to do the same operation with opencv module and preferably faster.
In next operation I have to map the lanes segmented in second image on the source image road lanes. I think I have to use the second image as mask and use cv2.bitwise_andto do job right? Can anybody help me?
thank you guys
If you want to color the image where the mask exists, then this is one way using Python/OpenCV. In place of bitwise_and, you simply have to do numpy coloring where the mask is white. Note again, your images are not the same size and I do not know how best to align them. I leave that to you. I am using your two input images as in my other answer. The code is nearly the same.
import cv2
import numpy as np
# read image
img = cv2.imread('road.png')
ht, wd, cc = img.shape
print(img.shape)
# read mask as grayscale
gray = cv2.imread('road_mask.png', cv2.IMREAD_GRAYSCALE)
hh, ww = gray.shape
print(gray.shape)
# get minimum dimensions
hm = min(ht, hh)
wm = min(wd, ww)
print(hm, wm)
# crop img and gray to min dimensions
img = img[0:hm, 0:wm]
gray = gray[0:hm, 0:wm]
# threshold gray as mask
thresh = cv2.threshold(gray,128,255,cv2.THRESH_BINARY)[1]
print(thresh.shape)
# apply mask to color image
result = img.copy()
result[thresh==255] = (0,0,255)
cv2.imshow('image', img)
cv2.imshow('gray', gray)
cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save results
cv2.imwrite('road_colored_by_mask.png', result)
Your images are not the same size. To mask the black/white image onto the color image, they need to align. I tried to simply crop them to the same minimum dimensions at the top left corner, but that did not align them properly.
However, this Python/OpenCV code will give you some idea how to start once you figure out how to align them.
Color Input:
B/W Lane Image:
import cv2
import numpy as np
# read image
img = cv2.imread('road.png')
ht, wd, cc = img.shape
print(img.shape)
# read mask as grayscale
gray = cv2.imread('road_mask.png', cv2.IMREAD_GRAYSCALE)
hh, ww = gray.shape
print(gray.shape)
# get minimum dimensions
hm = min(ht, hh)
wm = min(wd, ww)
print(hm, wm)
# crop img and gray to min dimensions
img = img[0:hm, 0:wm]
gray = gray[0:hm, 0:wm]
# threshold gray as mask
thresh = cv2.threshold(gray,128,255,cv2.THRESH_BINARY)[1]
print(thresh.shape)
# make thresh 3 channels as mask
mask = cv2.merge((thresh, thresh, thresh))
# apply mask to color image
result = cv2.bitwise_and(img, mask)
cv2.imshow('image', img)
cv2.imshow('gray', gray)
cv2.imshow('thresh', thresh)
cv2.imshow('mask', mask)
cv2.imshow('masked image', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save results
cv2.imwrite('road_masked_on_black.png', result)
I have a video with opaque logo, my goal is to identify area of image that remain still and extract it.
this is my code:
import cv2
import numpy as np
import imutils
c = cv2.VideoCapture('sky.mp4')
_,f = c.read()
avg2 = np.float32(f)
while(1):
_,f = c.read()
cv2.accumulateWeighted(f,avg2,0.005)
#cv2.accumulateWeighted(f,avg2,0.01)
res2 = cv2.convertScaleAbs(avg2)
# load the query image, compute the ratio of the old height
# to the new height, clone it, and resize it
ratio = res2.shape[0] / 300.0
orig = res2.copy()
res2 = imutils.resize(res2, height = 600)
# convert the image to grayscale, blur it, and find edges
# in the image
gray = cv2.cvtColor(res2, cv2.COLOR_BGR2GRAY)
gray = cv2.bilateralFilter(gray, 11, 17, 17)
edged = cv2.Canny(gray, 30, 200)
cv2.imshow('img',f)
cv2.imshow('avg2',edged)
k = cv2.waitKey(20)
if k == 27:
break
cv2.destroyAllWindows()
c.release()
The cv2.accumulateWeighted funtion, after time pass, permits to clearly identify parts that remain mostly still on the frames.
orig frame part:
edged averaged frame part:
How can I create a mask for the entire averaged edged part, crop it and save it in a separate image?
You can use cv2.findContours() to do connected component analysis. Then use cv2.boundingRect() to get the bounding box. Then you can crop the image using img[r1:r2, c1:c2] using Numpy slicing.
I work with 3D volumes produced by confocal microscopy. These images have x,y,z dimensions around ~1024,1024,50 and are stored in a .tif file.
I want to apply OpenCV-python cv2.adaptiveThreshold to the whole image stack. The below code works well for a 2D image (1024,1024,1). How can I expand it for the whole volume and save the output .tif file?
img = cv2.imread("1024x1024x40.tif")
gimg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
th = cv2.adaptiveThreshold(gimg, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 7, -20)
cv2.imshow('original',img)
cv2.imshow('Adaptive threshold',th)
cv2.waitKey(0)
cv2.destroyAllWindows()
Thanks!
Using the bioformats package:
I don't have test data but using this answer as a guide, you might try something like the following:
import javabridge
import bioformats
javabridge.start_vm(class_path=bioformats.JARS)
path_to_data = '/path/to/data/file_name.tif'
xml_string = bioformats.get_omexml_metadata(path_to_data)
ome = bioformats.OMEXML(xml_string) # be sure everything is ascii
iome = ome.image(0) # e.g. first image
reader = bioformats.ImageReader(path_to_data)
raw_data = []
for z in range(iome.Pixels.get_SizeZ()):
img = reader.read(z=z, series=0, rescale=False)
gimg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
th = cv2.adaptiveThreshold(gimg, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 7, -20)
img = cv2.bitwise_and(img, img, mask = th)
raw_data.append(img)
bioformats.write_image("/path/to/data/file_name_OUTPUT.tif", raw_data)