how to get the text from the image? - python-3.x

I am trying to get coordinate from a map, I took the coordinate part and I applied on it OCR using Pytesseract but I can't get the coordinate. this is the link to the image "https://ibb.co/hVynk2b" i tried this script:
import numpy as np
import cv2 as cv
%matplotlib inline
from matplotlib import pyplot as plt
img = cv.imread('a.jpg')
corped = img[460:700, 700:1000]
image=cv2.cvtColor(corped,cv2.COLOR_BGR2GRAY)
se=cv2.getStructuringElement(cv2.MORPH_RECT , (8,8))
bg=cv2.morphologyEx(image, cv2.MORPH_DILATE, se)
out_gray=cv2.divide(image, bg, scale=255)
out_binary=cv2.threshold(out_gray, 0, 255, cv2.THRESH_OTSU )[1]
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
from pytesseract import Output
d = pytesseract.image_to_data(out_binary, output_type=Output.DICT)
print(d['text'])

It seems to work for me. I ran the code you pasted, but cleaned it up a bit:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
import pytesseract
from pytesseract import Output
img = cv.imread(r'a.jpg')
cropped = img[460:700, 700:1000]
image = cv.cvtColor(cropped, cv.COLOR_BGR2GRAY)
se = cv.getStructuringElement(cv.MORPH_RECT, (8, 8))
bg = cv.morphologyEx(image, cv.MORPH_DILATE, se)
out_gray = cv.divide(image, bg, scale=255)
out_binary = cv.threshold(out_gray, 0, 255, cv.THRESH_OTSU)[1]
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
d = pytesseract.image_to_data(out_binary, output_type=Output.DICT)
print(d['text'])
and it returns '35°21'24°'
I did notice however that pytesseract doesn't catch the vertical text. You can either add in and mess around with the config parameter when calling image_to_data or you can simply rotate the image 90 degrees clockwise and run it again:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
import pytesseract
from pytesseract import Output
img = cv.imread(r'C:\Users\guneh\Desktop\a.jpg')
rotate = cv.rotate(cropped, cv.ROTATE_90_CLOCKWISE)
image = cv.cvtColor(rotate, cv.COLOR_BGR2GRAY)
se = cv.getStructuringElement(cv.MORPH_RECT, (8, 8))
bg = cv.morphologyEx(image, cv.MORPH_DILATE, se)
out_gray = cv.divide(image, bg, scale=255)
out_binary = cv.threshold(out_gray, 0, 255, cv.THRESH_OTSU)[1]
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
d = pytesseract.image_to_data(out_binary, output_type=Output.DICT)
print(d['text'])
returns '10°37'02"'

Related

Detection of walls in a plan

I work on a subject which is detection of walls in an image.
So the method I use is:
featur.Canny of skimage I got this image
FindContours of OpenCV-python
But it detects no segments at all
Import part:
import matplotlib.pyplot as plt
import skimage.segmentation as seg
import skimage.filters as filters
from skimage import feature
from skimage.segmentation import (morphological_chan_vese,
morphological_geodesic_active_contour,
inverse_gaussian_gradient,
checkerboard_level_set, mark_boundaries)
from skimage import data, img_as_float
import cv2 as cv2
The code:
img = cv2.imread(image_png, 0)
img_base = img
img = feature.canny(img, sigma=3)
dpi = 72
plt.figure(figsize=(9000/dpi, 9000/dpi), dpi=dpi)
plt.imshow(img, cmap="Greys", aspect="equal")
plt.axis("off")
plt.savefig("test_new_canny.png")
img = cv2.imread("test_new_canny.png", 0)
image_base = cv2.imread("./image_test/rdc.png", 0)
contours, _ = cv2.findContours(img, cv2.RETR_CCOMP , cv2.CHAIN_APPROX_SIMPLE )
contours = cv2.drawContours(image_base, contours, -1, (0,255,0), 3)
Image.fromarray(contours).save("test_contours.png")
Do you know why the detection doesn't work?
So I use a second method, Computes Felsenszwalb’s efficient graph based image segmentation, with Skimage
I obtain something with a small image but with a larger one the algo never finish the treatment.
Any ideas?

How to get ˚ in openCV

I want to write ˚ (degree character) in my image. I'm using Python and OpenCV.
The character, however, is shown as ??. This is my code:
import numpy as np
import cv2
import matplotlib.pyplot as plt
read=np.ones((500,500))
temp=100
read=cv2.putText(read,'{:>8.2f} ℃'.format(temp),(20,100), font, 2,(255,255,255),4,cv2.LINE_AA)
plt.imshow(read)
This is the output:
Thanks you, eldesgraciado,
PIL works well
import numpy as np
import cv2
import matplotlib.pyplot as plt
from PIL import Image, ImageFont, ImageDraw
font_path = 'C:\Windows\Fonts\Arial.ttf'
font_size = 48
font = ImageFont.truetype(font_path, font_size)
read=np.ones((500,500))
temp=100
img=Image.fromarray(read)
draw=ImageDraw.Draw(img)
draw.text((0, 50),'{:>9.2f} ˚C'.format(temp), font=font, fill=255)
read=np.array(img)
plt.imshow(read)

How to plot 3d rgb histogram of a colored image in python

I want to plot a 3d histogram of a colored image but I can only plot R and G value. what am I doing wrong here? or is there an easier way to do so
import numpy as np
import matplotlib.image as mpimg
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
img = mpimg.imread('model/obj4__0.png')
pixels = img.shape[0]*img.shape[1]
channels = 3
data = np.reshape(img[:, :, :channels], (pixels, channels))
histo_rgb, _ = np.histogramdd(data, bins=256)
histo_rg = np.sum(histo_rgb, 2)
levels = np.arange(256)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for g in levels:
ax.bar(levels, histo_rg[:, g], zs=g, zdir='y', color='r')
ax.set_xlabel('Red')
ax.set_ylabel('Green')
ax.set_zlabel('Number of pixels')
plt.show()
If I understand your question well, I have the same issue, and found this: https://www.bogotobogo.com/python/OpenCV_Python/python_opencv3_image_histogram_calcHist.php
Here is the code for your question:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('images/GoldenGateSunset.png', -1)
cv2.imshow('GoldenGate',img)
color = ('b','g','r')
for channel,col in enumerate(color):
histr = cv2.calcHist([img],[channel],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.title('Histogram for color scale picture')
plt.show()
while True:
k = cv2.waitKey(0) & 0xFF
if k == 27: break # ESC key to exit
cv2.destroyAllWindows()
Note that this use cv2 functions but you can convert it to works with Numpy.
I will try to figure out with numpy and give you an update.

How can I make a transparent background?

I have a .csv file which contains some data where x, y, x1, y1 are the coordinate points, and p is the value. My below code is working very well for plotting, but when I am plotting the data, I am getting a background color like the purple color. I don't want any color in the background. I want the background will be Transparent. My ultimate goal is overlying this result over an image. I am new in Python. Any help will be highly appreciated.
Download link of the .csv file here or link-2 or link-3
I am getting below result
My Code
import matplotlib.pyplot as plt
from scipy import ndimage
import numpy as np
import pandas as pd
from skimage import transform
from PIL import Image
import cv2
x_dim=1200
y_dim=1200
# Read CSV
df = pd.read_csv("flower_feature.csv")
# Create numpy array of zeros os same size
array = np.zeros((x_dim, y_dim), dtype=np.uint8)
for index, row in df.iterrows():
x = np.int(row["x"])
y = np.int(row["y"])
x1 = np.int(row["x1"])
y1 = np.int(row["y1"])
p = row["p"]
array[x:x1,y:y1] = p
map = ndimage.filters.gaussian_filter(array, sigma=16)
plt.imshow(map)
plt.show()
As per Ghassen's suggestion I am getting below results. I am still not getting the transparent background.
When Alpha =0
When alpha =0.5
When alpha =1
try with this code :
import matplotlib.pyplot as plt
from scipy import ndimage
import numpy as np
import pandas as pd
x_dim=1200
y_dim=1200
# Read CSV
df = pd.read_csv("/home/rosafi/Downloads/flower_feature.csv")
# Create numpy array of zeros os same size
array = np.ones((x_dim, y_dim), dtype=np.uint8)
for index, row in df.iterrows():
x = np.int(row["x"])
y = np.int(row["y"])
x1 = np.int(row["x1"])
y1 = np.int(row["y1"])
p = row["p"]
array[x:x1,y:y1] = p
map = ndimage.filters.gaussian_filter(array, sigma=16)
map = np.ma.masked_where(map == 0, map)
plt.imshow(map)
plt.show()
output:
I solved this issue by masking out the values where values ==0. The code will be
from mpl_toolkits.axes_grid1 import make_axes_locatable
masked_data = np.ma.masked_where(map == 0, map)

Store the Spectrogram as Image in Python

I want to store the STFT spectrogram of the audio as image. The code below shows a spectrogram to me as output, but when saved as image I get a different image.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
audio_name = '---.au'
hop_length = 512
window_size = 1024
import librosa
y, sr = librosa.load(audio_name)
window = np.hanning(window_size)
out = librosa.core.spectrum.stft(y, n_fft = window_size, hop_length = hop_length,
window=window)
out = 2 * np.abs(out) / np.sum(window)
import librosa.display
librosa.display.specshow(librosa.amplitude_to_db(out,ref=np.max),
y_axis='log', x_axis='time')
from PIL import Image
img = Image.fromarray(out)
if img.mode != 'RGBA':
img = img.convert('RGBA')
img.save('output.png')
But when I save it the output file is a black image.
I want to save the exact image of the spectogrm.
If you want exactly what librosa.display.spectrogram() will show, then use matplotlib to save the plot to a file:
import matplotlib.pyplot as plt
import librosa.display
import numpy as np
import pandas as pd
import librosa
filename = librosa.util.example_audio_file()
y, sr = librosa.load(filename)
y = y[:100000] # shorten audio a bit for speed
window_size = 1024
window = np.hanning(window_size)
stft = librosa.core.spectrum.stft(y, n_fft=window_size, hop_length=512, window=window)
out = 2 * np.abs(stft) / np.sum(window)
# For plotting headlessly
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
fig = plt.Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
p = librosa.display.specshow(librosa.amplitude_to_db(out, ref=np.max), ax=ax, y_axis='log', x_axis='time')
fig.savefig('spec.png')
spec.png:
If the desired is to get just the data in the spectrogram, stored as an image, then see this answer.

Resources