start with poetry
This commit is contained in:
parent
61db3d9216
commit
662e10d1a4
|
|
@ -11,7 +11,7 @@ image = cv2.imread('capture.png')
|
|||
|
||||
# Create a window
|
||||
cv2.namedWindow('image')
|
||||
# dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None)
|
||||
|
||||
# Create trackbars for color change
|
||||
# Hue is from 0-179 for Opencv
|
||||
cv2.createTrackbar('dp', 'image', 0, 300, nothing)
|
||||
|
|
@ -33,7 +33,7 @@ cv2.setTrackbarPos('maxRadius', 'image', 50)
|
|||
dp = minDist = param1 = param2 = minRadius = maxRadius = 0
|
||||
pdp = pminDist = pparam1 = pparam2 = pminRadius = pmaxRadius = 0
|
||||
|
||||
while (1):
|
||||
while True:
|
||||
# Get current positions of all trackbars
|
||||
dp = cv2.getTrackbarPos('dp', 'image')
|
||||
minDist = cv2.getTrackbarPos('minDist', 'image')
|
||||
|
|
@ -44,16 +44,17 @@ while (1):
|
|||
|
||||
img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
||||
gradient = cv2.HOUGH_GRADIENT
|
||||
circles = cv2.HoughCircles(img, gradient, dp/100.0, minDist,
|
||||
param1=param1, param2=param2, minRadius=minRadius,
|
||||
circles = cv2.HoughCircles(img, gradient, dp/100.0, minDist, param1=param1,
|
||||
param2=param2, minRadius=minRadius,
|
||||
maxRadius=maxRadius)
|
||||
|
||||
# Print if there is a change in HSV value
|
||||
if ((pdp != dp) | (pminDist != minDist) | (pparam1 != param1) | (
|
||||
pparam2 != param2) | (pminRadius != minRadius) | (
|
||||
pmaxRadius != maxRadius)):
|
||||
print("dp: {}, minDist: {}, param1: {}, param2: {}, minRadius: {}, maxRadius: {}"
|
||||
.format(dp, minDist, param1, param2, minRadius, maxRadius))
|
||||
print(f"dp: {dp}, minDist: {minDist}, param1: {param1}, "
|
||||
f"param2: {param2}, minRadius: {minRadius}, "
|
||||
f"maxRadius: {maxRadius}")
|
||||
pdp = dp
|
||||
pminDist = minDist
|
||||
pparam1 = param1
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import cv2
|
||||
import numpy as np
|
||||
|
||||
|
||||
def nothing(x):
|
||||
print(x)
|
||||
pass
|
||||
|
||||
|
||||
# Load image
|
||||
image = cv2.imread('capture.png')
|
||||
|
||||
|
|
@ -28,7 +31,7 @@ cv2.setTrackbarPos('VMax', 'image', 255)
|
|||
hMin = sMin = vMin = hMax = sMax = vMax = 0
|
||||
phMin = psMin = pvMin = phMax = psMax = pvMax = 0
|
||||
|
||||
while(1):
|
||||
while True:
|
||||
# Get current positions of all trackbars
|
||||
hMin = cv2.getTrackbarPos('HMin', 'image')
|
||||
sMin = cv2.getTrackbarPos('SMin', 'image')
|
||||
|
|
@ -47,8 +50,15 @@ while(1):
|
|||
result = cv2.bitwise_and(image, image, mask=mask)
|
||||
|
||||
# Print if there is a change in HSV value
|
||||
if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
|
||||
print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
|
||||
if(
|
||||
(phMin != hMin) |
|
||||
(psMin != sMin) |
|
||||
(pvMin != vMin) |
|
||||
(phMax != hMax) |
|
||||
(psMax != sMax) |
|
||||
(pvMax != vMax)):
|
||||
print(f"(hMin = {hMin} , sMin = {sMin}, vMin = {vMin}), "
|
||||
f"(hMax = {hMax}, sMax = {sMax}, vMax = {vMax})")
|
||||
phMin = hMin
|
||||
psMin = sMin
|
||||
pvMin = vMin
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import cv2
|
||||
|
||||
|
||||
def get_video():
|
||||
camera = cv2.VideoCapture()
|
||||
camera.open('http://10.0.0.22:81')
|
||||
|
|
@ -12,5 +13,6 @@ def get_video():
|
|||
cv2.waitKey(1)
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
get_video()
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
import yaml
|
||||
import logging
|
||||
|
||||
|
||||
def get_config(config_filepath: str) -> dict:
|
||||
with open(config_filepath) as f:
|
||||
|
|
@ -9,14 +8,14 @@ def get_config(config_filepath: str) -> dict:
|
|||
|
||||
|
||||
def create_logger():
|
||||
import multiprocessing, logging
|
||||
import multiprocessing
|
||||
import logging
|
||||
logger = multiprocessing.get_logger()
|
||||
logger.setLevel(logging.INFO)
|
||||
formatter = logging.Formatter(\
|
||||
'[%(asctime)s| %(levelname)s| %(message)s')
|
||||
import os, os.path
|
||||
if not os.path.exists("logs/"):
|
||||
os.makedirs("logs/")
|
||||
formatter = logging.Formatter('[%(asctime)s| %(levelname)s| %(message)s')
|
||||
import os.path
|
||||
if not os.path.exists("logs"):
|
||||
os.makedirs("logs")
|
||||
handler = logging.FileHandler('logs/water.log')
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import os
|
||||
import time
|
||||
from queue import Queue
|
||||
from threading import Thread
|
||||
|
||||
from src.helpers import get_config, create_logger
|
||||
from src.mqtt import get_mqtt_client
|
||||
from src.water import ReportAmount, Water
|
||||
from src.water_meter import WaterMeter
|
||||
from queue import Queue
|
||||
from src.water_meter.helpers import get_config, create_logger
|
||||
from src.water_meter.mqtt import get_mqtt_client
|
||||
from src.water_meter.water import ReportAmount
|
||||
from src.water_meter.water_meter import WaterMeter
|
||||
|
||||
CONFIG_FILE_PATH = os.getenv("MQTT_CAMERA_CONFIG", "./config.yml")
|
||||
CONFIG = get_config(CONFIG_FILE_PATH)
|
||||
|
|
@ -16,15 +16,17 @@ MQTT_PORT = CONFIG["mqtt"]["port"]
|
|||
|
||||
|
||||
def producer():
|
||||
logger = create_logger()
|
||||
logger.info("From producer")
|
||||
water_meter = WaterMeter('http://10.0.0.22:81', img='capture_4.png', debug=False)
|
||||
logger_producer = create_logger()
|
||||
logger_producer.info("From producer")
|
||||
water_meter = WaterMeter('http://10.0.0.22:81',
|
||||
img='capture_4.png',
|
||||
debug=False)
|
||||
water_meter.loop(q)
|
||||
|
||||
|
||||
def consumer():
|
||||
logger = create_logger()
|
||||
logger.info("From consumer")
|
||||
logger_consumer = create_logger()
|
||||
logger_consumer.info("From consumer")
|
||||
evaluator = ReportAmount(client, topic='water_meter/litre')
|
||||
while True:
|
||||
water = q.get(True)
|
||||
|
|
@ -32,28 +34,28 @@ def consumer():
|
|||
|
||||
|
||||
def main():
|
||||
client = get_mqtt_client()
|
||||
client.connect(MQTT_BROKER, port=MQTT_PORT)
|
||||
time.sleep(5)
|
||||
while True:
|
||||
from random import randrange
|
||||
value = randrange(10)
|
||||
client.publish('water_meter/litre', 1)
|
||||
client.publish('water_meter/litre', value)
|
||||
time.sleep(3)
|
||||
|
||||
|
||||
def main2():
|
||||
|
||||
producer()
|
||||
consumer_thread = Thread(target=consumer)
|
||||
consumer_thread.daemon = True
|
||||
consumer_thread.start()
|
||||
|
||||
producer()
|
||||
|
||||
|
||||
logger = create_logger()
|
||||
logger.info("From main")
|
||||
q = Queue()
|
||||
client = get_mqtt_client()
|
||||
client.connect(MQTT_BROKER, port=MQTT_PORT)
|
||||
|
||||
if __name__ == '__main__':
|
||||
logger = create_logger()
|
||||
logger.info("From main")
|
||||
q = Queue()
|
||||
client = get_mqtt_client()
|
||||
client.connect(MQTT_BROKER, port=MQTT_PORT)
|
||||
main2()
|
||||
|
|
@ -2,9 +2,10 @@
|
|||
Some boilerplate code to handle MQTT.
|
||||
"""
|
||||
import os
|
||||
|
||||
from paho.mqtt import client as mqtt
|
||||
|
||||
from src.helpers import get_config
|
||||
from src.water_meter.helpers import get_config
|
||||
|
||||
CONFIG_FILE_PATH = os.getenv("MQTT_CAMERA_CONFIG", "./config.yml")
|
||||
CONFIG = get_config(CONFIG_FILE_PATH)
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
from dataclasses import dataclass
|
||||
import time
|
||||
from threading import Thread
|
||||
from dataclasses import dataclass
|
||||
from queue import Queue
|
||||
from threading import Thread
|
||||
|
||||
from .helpers import create_logger
|
||||
|
||||
|
||||
@dataclass
|
||||
class Water:
|
||||
percent_of_a_litre: int
|
||||
|
|
@ -15,6 +17,7 @@ def coroutine(fn):
|
|||
v = fn(*args, **kwargs)
|
||||
v.send(None)
|
||||
return v
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
|
|
@ -45,20 +48,19 @@ class ReportAmount:
|
|||
self.logger.info(f"New litre, publish, amount: {self.litre}")
|
||||
self.last_send_timestamp = water.timestamp
|
||||
self.current_state = self.reported
|
||||
#print(f"REPORT: Percentage is {percentage}, time {water.timestamp}")
|
||||
# print(f"REPORT: Percentage is {percentage}, time {water.timestamp}")
|
||||
|
||||
@coroutine
|
||||
def _reported(self):
|
||||
while True:
|
||||
water = yield
|
||||
percentage = water.percent_of_a_litre
|
||||
time_diff = water.timestamp - self.last_send_timestamp
|
||||
# time_diff = water.timestamp - self.last_send_timestamp
|
||||
if percentage > 25:
|
||||
self.current_state = self.redo
|
||||
# print(f"REPORTED: Wait until percentage is 50, {percentage}"
|
||||
# f", timediff: {time_diff}")
|
||||
|
||||
|
||||
@coroutine
|
||||
def _redo(self):
|
||||
while True:
|
||||
|
|
@ -67,7 +69,6 @@ class ReportAmount:
|
|||
if percentage < 20:
|
||||
print("Change to report")
|
||||
self.current_state = self.report
|
||||
#print(f"REDO: Percentage is {percentage}, time {water.timestamp}")
|
||||
|
||||
|
||||
def producer():
|
||||
|
|
@ -77,7 +78,7 @@ def producer():
|
|||
|
||||
|
||||
def consumer():
|
||||
evaluator = ReportAmount()
|
||||
evaluator = ReportAmount(None, topic='water_meter/litre')
|
||||
while True:
|
||||
water = q.get(True)
|
||||
evaluator.send(water)
|
||||
|
|
@ -95,6 +96,3 @@ if __name__ == '__main__':
|
|||
t1.start()
|
||||
|
||||
q.join()
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
import math
|
||||
import sys
|
||||
import time
|
||||
|
||||
import cv2
|
||||
import os
|
||||
import numpy as np
|
||||
import imutils
|
||||
import numpy as np
|
||||
from scipy.spatial import distance as dist
|
||||
from .water import Water
|
||||
|
||||
from .helpers import create_logger
|
||||
from .water import Water
|
||||
|
||||
|
||||
class WaterMeter(object):
|
||||
|
|
@ -43,6 +42,7 @@ class WaterMeter(object):
|
|||
img = cv2.imread(self.img)
|
||||
self.get_degree(img)
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
def loop(self, queue):
|
||||
bad_frame = 0
|
||||
while not self._quit:
|
||||
|
|
@ -62,7 +62,7 @@ class WaterMeter(object):
|
|||
ret, current_frame = self.cap.read()
|
||||
# the connection broke, or the stream came to an end
|
||||
if (not ret) or (current_frame is None):
|
||||
# ToDo Logging error frame
|
||||
self.logger.error("Bad frame")
|
||||
bad_frame += 1
|
||||
continue
|
||||
else:
|
||||
|
|
@ -87,6 +87,7 @@ class WaterMeter(object):
|
|||
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
|
||||
cv2.putText(current_frame, f"%: {self.percent}", (10, 60),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
|
||||
|
||||
cv2.imshow("Degree", current_frame)
|
||||
cv2.waitKey(1)
|
||||
|
||||
|
|
@ -99,8 +100,7 @@ class WaterMeter(object):
|
|||
def get_degree(self, frame):
|
||||
img = frame
|
||||
dials = self.find_circle(img)
|
||||
# Init value out of range
|
||||
deg = -1
|
||||
|
||||
dial_one_litre = []
|
||||
if not dials:
|
||||
return -1, img
|
||||
|
|
@ -174,8 +174,15 @@ class WaterMeter(object):
|
|||
except cv2.error:
|
||||
return None
|
||||
# Find suitable hsv number by running detect_hsv.py
|
||||
lower_red_hue = self.create_hue_mask(hsv, [0, 100, 100], [10, 255, 255])
|
||||
higher_red_hue = self.create_hue_mask(hsv, [170, 80, 110], [179, 255, 255])
|
||||
lower_red_hue = self.create_hue_mask(hsv,
|
||||
[0, 100, 100],
|
||||
[10, 255, 255]
|
||||
)
|
||||
|
||||
higher_red_hue = self.create_hue_mask(hsv,
|
||||
[170, 80, 110],
|
||||
[179, 255, 255]
|
||||
)
|
||||
|
||||
mask = cv2.bitwise_or(lower_red_hue, higher_red_hue)
|
||||
needle = cv2.GaussianBlur(mask, (5, 5), 0)
|
||||
|
|
@ -232,11 +239,11 @@ class WaterMeter(object):
|
|||
height, width, _ = cut.shape
|
||||
|
||||
for (x, y) in extreme_points:
|
||||
D = dist.euclidean((x, y), (int(height/2), int(width/2)))
|
||||
distance = dist.euclidean((x, y), (int(height/2), int(width/2)))
|
||||
if not length_from_centre:
|
||||
length_from_centre = {'x': x, 'y': y, 'distance': D}
|
||||
elif D > length_from_centre['distance']:
|
||||
length_from_centre = {'x': x, 'y': y, 'distance': D}
|
||||
length_from_centre = {'x': x, 'y': y, 'distance': distance}
|
||||
elif distance > length_from_centre['distance']:
|
||||
length_from_centre = {'x': x, 'y': y, 'distance': distance}
|
||||
|
||||
if self.debug:
|
||||
cv2.line(cut, (length_from_centre['x'], length_from_centre['y']),
|
||||
|
|
@ -259,8 +266,11 @@ class WaterMeter(object):
|
|||
self.percent = sum(self.percent_list) / len(self.percent_list)
|
||||
self.percent = round(self.percent * 100)
|
||||
|
||||
if __name__ == '__main__':
|
||||
water_meter = WaterMeter('http://10.0.0.22:81', img='capture_4.png', debug=False)
|
||||
water_meter.loop()
|
||||
#water_meqter.read()
|
||||
|
||||
if __name__ == '__main__':
|
||||
water_meter = WaterMeter('http://10.0.0.22:81',
|
||||
img='capture_4.png',
|
||||
debug=False)
|
||||
water_meter.loop()
|
||||
# water_meqter.read()
|
||||
|
||||
Loading…
Reference in New Issue