# Techiebouncer

Get Informed out of Data

# Measuring Device Using Scipy on Raspberry Pi

Raspberry Pi and its camera is really a powerful tool to exhibit various iteration of the new scheme of products.

Obviously, these devices(the products you make out of rpi) very much depend on the programming and use of raspberry pi in its own domain.

Many counts, this project is more centered around OpenCV-python and scipy, but raspberry pi plays a vital role in being it as a product as it is very mobile-oriented.

Measurement is an important thing in real-world aspect, What special about Raspberry pi based Measuring device.

This makes an interesting debate on measuring a pixel vs measuring on a scale.

"Machine-made hardware vs Machine coded software"

The steps for doing this are centric around image manipulation techniques, like finding contours and its corner points among the objects placed in for measurement and play around it.

Okay, let's get into programming,

Python3 dependencies

• Scipy
• Opencv
• imutils
If you don't have the above library kindly install using pip command.

from scipy.spatial.distance import euclidean
from imutils import perspective
from imutils import contours
import numpy as np
import imutils
import cv2

# Function to show array of images (intermediate results)
def show_images(images):
for i, img in enumerate(images):
cv2.imshow("image_" + str(i), img)
cv2.waitKey(0)
cv2.destroyAllWindows()

img_path = "images/coins.png"

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (9, 9), 0)

edged = cv2.Canny(blur, 50, 100)
edged = cv2.dilate(edged, None, iterations=1)
edged = cv2.erode(edged, None, iterations=1)

#show_images([blur, edged])

# Find contours
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

# Sort contours from left to right as leftmost contour is reference object
(cnts, _) = contours.sort_contours(cnts)

# Remove contours which are not large enough
cnts = [x for x in cnts if cv2.contourArea(x) > 100]

#cv2.drawContours(image, cnts, -1, (0,255,0), 3)

#show_images([image, edged])
#print(len(cnts))

# Reference object dimensions
# Here for reference I have used a 2cm x 2cm square
ref_object = cnts[0]
box = cv2.minAreaRect(ref_object)
box = cv2.boxPoints(box)
box = np.array(box, dtype="int")
box = perspective.order_points(box)
(tl, tr, br, bl) = box
dist_in_pixel = euclidean(tl, tr)
dist_in_cm = 2
pixel_per_cm = dist_in_pixel/dist_in_cm

# Draw remaining contours
for cnt in cnts:
box = cv2.minAreaRect(cnt)
box = cv2.boxPoints(box)
box = np.array(box, dtype="int")
box = perspective.order_points(box)
(tl, tr, br, bl) = box
cv2.drawContours(image, [box.astype("int")], -1, (0, 0, 255), 2)
mid_pt_horizontal = (tl[0] + int(abs(tr[0] - tl[0])/2), tl[1] + int(abs(tr[1] - tl[1])/2))
mid_pt_verticle = (tr[0] + int(abs(tr[0] - br[0])/2), tr[1] + int(abs(tr[1] - br[1])/2))
wid = euclidean(tl, tr)/pixel_per_cm
ht = euclidean(tr, br)/pixel_per_cm
cv2.putText(image, "{:.1f}cm".format(wid), (int(mid_pt_horizontal[0] - 15), int(mid_pt_horizontal[1] - 10)),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 2)
cv2.putText(image, "{:.1f}cm".format(ht), (int(mid_pt_verticle[0] + 10), int(mid_pt_verticle[1])),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 2)

show_images([image])

I have used a preloaded image, but also tested with the picam just change the image source line into cv2.VideoCapture(0) before doing it kindly enable the camera.

Here is my output, hope you could also try it out.