Detection of walls in a plan - python-3.x

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?

Related

Numpy error trying to use difference hashing with the ImageHash library

I am trying to perform difference hashing with the python ImageHash library and keep getting a numpy error.
The error:
File "/Users/testuser/Desktop/test_folder/test_env/lib/python3.8/site-packages/imagehash.py", line 252, in dhash
image = image.convert("L").resize((hash_size + 1, hash_size), Image.ANTIALIAS)
AttributeError: 'numpy.ndarray' object has no attribute 'convert'
The code:
from PIL import Image
from cv2 import cv2
import imagehash
import numpy as np
def hash_and_compare(image1, image2):
image1 = image1
image2 = image2
# read images
image1 = cv2.imread(image1)
image2 = cv2.imread(image2)
# convert to grayscale
image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
# resize images
image1 = cv2.resize(image1, (9, 8))
image2 = cv2.resize(image2, (9, 8))
# hash images
image1_hash = imagehash.dhash(image1)
image2_hash = imagehash.dhash(image2)
# compute hamming distance
distance = image1_hash - image2_hash
if image1_hash <= 10:
print(distance)
print('match')
else:
print(distance)
print('no match')
hash_and_compare('/Users/testuser/Desktop/test_folder/game_name056496.png', '/Users/testuser/Desktop/test_folder/game_name499761.png')
as it is mentioned in imagehash library's document, #image must be a PIL instance.. so you cant set numpy array as input of the dshash function.if you want do some preprocess with opencv, you should convert it into PIL array before setting it into dhash, like this :
import numpy as np
from PIL import Image
...
some preprocess
...
# You may need to convert the color.
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(img)
image1_hash = imagehash.dhash(im_pil)

how to get the text from the image?

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"'

Making Predictions (classifying chess pieces)

I am trying to identify all the pieces present on the Chessboard via machine learning.Currently I am predicting for a single piece.I want to load the trained model from the disk,loop through the board, get the playing square crop, and the model will predict the piece that is on that square.
I want to do like this- https://www.youtube.com/watch?v=jcFvrCsoY_w
This is my current code for prediction of single piece.Help me to loop through the board and get playing square crop like above video.
import cv2
import time
import os
import glob
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tensorflow.keras.models import load_model
model = load_model('/home/tejas/Videos/chess/model_50x50.hd5')
label_map = list('KQRBNP_kqrbnp')
def predict(img, model, img_size=(50,50), plot=False):
img = cv2.resize(img, img_size)
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY )
if plot:
plt.imshow(img, cmap='gray')
img = img.reshape(1, *img_size, 1) / 255
pred = model.predict(img)
return label_map[np.argmax(pred)]
path = '/media/tejas/creator/chess/train_data/black/r/r_90_1579252980.226565.jpg'
name_map = {
'K':'White King',
'Q':'White Queen',
'R':'White Rook',
'B':'White Bishop',
'N':'White Knight',1y0
'P':'White Pawn',
'_':'Empty Square',
'k':'Black King',
'q':'Black Queen',
'r':'Black Rook',
'b':'Black Bishop',
'n':'Black Knight',
'p':'Black Pawn',
}
img = cv2.imread(path)
pred = predict(img, model, plot=True)
print('The image is a', name_map[pred])
Thanks !!!

Thresholding infrared images

I want to analyze infrared images of solar panels and cut the panels from the images. As a first step I need to threshold the image. But if I do it with a example image from google like the one below I only get a black image. What I can do to improve?
import cv2
import numpy as np
img = cv2.imread('GooglePanelIR.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
ret,thresh1 = cv2.threshold(hsv[:,:,0],100,255,cv2.THRESH_BINARY)
cv2.imshow('cont imge', thresh1)
cv2.waitKey(0)
print(ret)
Since you need to threshold and its a grayscale image, import your image in grayscale.
This is what you are looking for.
import cv2
import numpy as np
img = cv2.imread('GooglePanelIR.png', 0)
ret,thresh1 = cv2.threshold(img,100,255,cv2.THRESH_BINARY)
cv2.imshow('cont imge', thresh1)
cv2.waitKey(0)
print(ret)

convert multidimensional numpy array to image

I have a numpy array(trainData.npy) for image processing. It contains 2000 images, garyscale and height 450 , width 600.
Train images shape:(2000, 1, 450, 600)
I'm looking for a way to plot or show one of these images. I've used this code but i'v got TypeError: Invalid dimensions for image data error/
import numpy as np
import matplotlib.pyplot as plt
img = img_train[0]
plt.imshow(img)
plt.show()
Just reshape your image:
import numpy as np
import matplotlib.pyplot as plt
img = img_train[0] #img has dim (ncolor=1, nlines=450, nrows=600)
img = reshape(450, 600) #img has dim (450, 600)
#img = img / img.max #if you need rescaling of greyscale to be in [0..1]
plt.imshow(img)
plt.show()
P.S.: I personally find it a bit more intuitive if pictures are dimensional-ordered (nlines, nrows, ncolorchanel) than your choice (ncolorchanel, nlines, nrows)

Resources