I'am working on a project to take pictures of the electricity meter reading and process the image to recognize the numbers and upload it to the cloud.
import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
image = cv2.imread('meter1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('Original image',image)
cv2.imshow('Gray image', gray)
threshold = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY, 83, 5)
cv2.imshow('Adaptive Gaussian', threshold)
cv2.imwrite('Binary.png',threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()
This is the code I have written so far which converts RGB image to grayscale and then used adaptive thresholding
This the image I used
What should I do next? Should I use tesseract OCR ? What are the ways to extract these digits or numbers
This is the image I got after running the code
Please help on how to proceed from this stage
Just check a point (or mean of a small ROI inside a segment) in each segment to recognize which digit is displayed.
Related
I have set of 17 images and one of them has a highlighted pixel for my use. But, when I merge these 17 images, I get the color but it diffuses out of the pixel boundaries and I start seeing some colored pixel in black background.
I am using PIL library for the merging. I am attaching my code and the images for the reference. Any help would be appreciated.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# Cretaing the Pixel array
from PIL import Image
from PIL import ImageColor
img_path = '/Volumes/MY_PASSPORT/JRF/cancer_genome/gopal_gen/png_files/'
image_list = []
for entry in os.listdir(img_path):
if entry.endswith('.png'):
entry = int(entry.rstrip('.csv.png'))
image_list.append(entry)
image_list.sort()
list_img = []
for j in range(len(image_list)):
stuff = str(image_list[j])+'.csv.png'
list_img.append(stuff)
#print(list_img[0])
images = [Image.open(img_path+x) for x in list_img]
widths, heights = zip(*(i.size for i in images))
total_width = sum(widths)
max_height = max(heights)
#print(total_width, max_height)
new_im = Image.new('RGB', (total_width, max_height))
x_offset = 0
for im in images:
new_im.paste(im, (x_offset,0))
#print(im.size)
x_offset += im.size[0]
#print(x_offset)
new_im.save(img_path+'final_result_image.jpg')
Here is the combined image:
The third column has a pixel highlighted.
Here is the zoomed in part with the problem.
The JPEG format is lossy - it is allowed to change your pixels to make the file smaller. If your image is a conventional photo of a real-life scene, this doesn't normally matter. If your data is a blocky, computer-generated image, or a set of classes from a classification process, it can go horribly wrong if you use JPEG.
So, the answer is to use PNG (or potentially TIFF) format for images that need to be lossless.
I have a text file from a thermal camera, I read it as an image with opencv python and it works, then I convert it to gray scale image and it works as well! so I can see the person in the image, the problem is that when I convert it to binary I get a blank black image and I need to draw contours around the person's face. So I wonder what might be the problem.
Hint: The text file is filled with temperature values, when I read it it views the whole person and then I do thresholding to the text file to make the values between 32.0 and 37.0 so that I would show only the face area and it works fine until I try to convert it to binary form.
Thanks in advance.
drive.google.com/file/d/1KgHmPAwcL_uPzVxwkigcQgCsY3jFjx8T/… #link to the file
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
import os
text=np.loadtxt('1_thermal.txt') #the text file of the image
text[text < 32.0]=0 #threshholding to plot and save only the face
text[text > 37.0]=0
plt.imshow(text,cmap='jet')
plt.savefig('text.png', dpi=300, bbox_inches='tight')
plt.show()
person = cv.imread('text.png')
plt.imshow(cv.cvtColor(person, cv.COLOR_BGR2RGB))
cv.imwrite('person.jpg', person)
# get binary image and apply Gaussian blur
person_gray = cv.cvtColor(person, cv.COLOR_BGR2GRAY)
person_preprocessed = cv.GaussianBlur(person_gray, (5, 5), 0)
cv.imwrite('person-Gray.png', person_preprocessed)
plt.imshow(cv.cvtColor(person_preprocessed, cv.COLOR_GRAY2RGB))
You can load the image into a Numpy array like this:
import numpy as np
# Load image
im = np.loadtxt('thermal.txt')
If we check im.dtype and im.shape, they are:
float64, (288, 382)
Now you want a binary image. I presume you mean it will only have values of True/False, so we will need a threshold. As the face is everything above 32, we will use 32 as the threshold:
# Threshold - greater than 32 becomes True, all else becomes False
binary = im > 32
binary will now be True where the face is and False elsewhere, but I guess you want an image that is black (0) where the background is, and white (255) elsewhere. So you want:
# Convert from False/True, to 0/255 and save
binary = (binary*255).astype(np.uint8)
cv2.imwrite('result.png', binary)
That gives:
In my code, I am creating a RGB array (256 * 256 * 3) and I need to show it.
I am having trouble creating a PIL image from a RGB array.
I wrote this code to explain:
import numpy as np
from PIL import Image
image = Image.open('img_test.png')
image.thumbnail((256, 256))
image = image.convert("RGB")
image = np.asarray(image, dtype=np.float32) / 255
PIL.Image.fromarray(image, "RGB").show()
I am getting this image back:
If I am using
import matplotlib.pyplot as plt
plt.imshow(image)
plt.show()
Then I am getting this image:
What am I doing wrong with this line?
PIL.Image.fromarray(image, "RGB").show()
You are expecting PIL to handle a 32-bit floating point RGB image, which it cannot - see here.
It can handle, amongst others:
RGB as three 8-bit integer values (RGB888), or
greyscale float32.
Just do
Image.fromarray(np.array(img).astype(np.uint8).transpose(1,2,0))
The line you mention seems fine, however, I wonder why you do this:
image = np.asarray(image, dtype=np.float32) / 255
If you replace that line by the following, it works for me, using either PIL or matplotlib to show the image:
image = np.asarray(image)
I am unable to print the text in Orange colored.I identified the edges of the image and then printed a text on it.
%matplotlib inline
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('ind_maharashtra.png',0)
edges = cv2.Canny(img,100,20)
cv2.imwrite('Edged_img.jpg',edges)
#plt.subplot(121)
img1 = cv2.imread('Edged_img.jpg',0)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img1,'JAI MAHARASHTRA !!',(70,150), font, 0.7,(255,69,0),2,cv2.LINE_8)
cv2.imshow('Maharashtra Map',img1)
#cv2.imshow('Maharashtra Map',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
The problem is that the image on which you are trying to draw ( the image named img1) is a gray-scale image since the 2nd argument of cv2.imread is 0 in the following line:
img1 = cv2.imread('Edged_img.jpg',0)
You have 2 options to fix this issue. First one is to load the image as a color image as follows:
img1 = cv2.imread('Edged_img.jpg')
Alternatively, if you want your canvas to have a gray-ish look, you can just replicate the single channel to form a 3 channel image as follows:
img1 = cv2.imread('Edged_img.jpg', 0)
img1 = cv2.cvtColor(img1, cv2.COLOR_GRAY2BGR)
You are loading your jpg in grayscale, so you will only be able to write grayscale to img1
OpenCV Imread docs
change this line
img1 = cv2.imread('Edged_img.jpg',0)
to
img1 = cv2.imread('Edged_img.jpg',1)
As you can see from the above linked docs, using these numbers is OK but you are actually setting a flag, so you could use the flag definition to make your code clearer. Coincidentally, if you had used the flags you would likely not have had this issue.
You can change your line to
img1 = cv2.imread('Edged_img', cv2.IMREAD_COLOR)
Look how much clearer, and understandable that is. Especially when you come back to this code/hand it over to another developer in a few months time.
Hey guys, I am trying to detect roads from satellite images.
After identifying the roads am getting the co-ordinates like roads coordinates and building coordinates.
The code which i tried to extract roads from satellite images.
Input image
from __future__ import print_function, division
from PIL import Image
import operator
import cv2
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
#reading image directly from current working directly
build_image = cv2.imread("avilla_san_marcos_gilbert,az.png")
#Doing MeanShift Filtering
#shifted = cv2.pyrMeanShiftFiltering(image, 21, 51)
#GrayScale Conversion
build_gray = cv2.cvtColor(build_image, cv2.COLOR_BGR2GRAY)
#OTSU Thresholding
thresh = cv2.threshold(build_gray, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imshow("OTSU Thresholded Image",thresh)
cv2.imwrite("OTSU_1 image.jpg",thresh)
#Checking Coordinates of White Pixels
build_white = np.argwhere(thresh == 255)
#Creating an array
build_data= np.array(build_white)
np.savetxt('build_coords.csv', build_data,delimiter=",")
#Checking Coordinates of White Pixels
road_white = np.argwhere(thresh == 0)
#Creating an array
road_data = np.array(road_white)
print(road_data)
#Saving vector of roads in a csv file
np.savetxt('road_coords.csv', road_data,delimiter=",")
Output image is plotted based on csv of Road pixel Coordinates
I have a problem with the output image obtained. It has detected trees i have to eliminate it by obtaining the pixel coordinates of tree.
So From that output image i have to extract the layout of the roads alone.Please try to help me out guys. Thanks in advance.