使用Python+OpenCV統計每日用電量(附代碼演練)

點擊下面卡片關注AI算法與圖像處理”,選擇加"星標"或“置頂”

重磅乾貨,第一時間送達

Hexing 預付費電錶歸PLN所有。這個工具可以用來代替必須由操作人員手動記錄的模擬儀表。現在用預付的電錶,我可以從KWH,安培,電壓和我的信用卡中看到更準確的測量。
本文將是一個使用OpenCV庫讀取預付表測量值的示例。目前,我使用raspberry pi 4來運行我的代碼,使用尺寸爲4 x 3.1 x 2.5cm的相機。如果你想要擴展USB線,我建議設置USB線的最大長度爲3米。超過3米會失去USB信號,導致攝像頭無法連接。
將相機面對預付費電錶脈衝LED燈:
設置好相機後,如上圖所示,就可以開始測量了。

讓我們編碼!

kwh_pln_sensor.py

我用這個代碼實時監控脈衝LED燈
首先,導入所需的庫

   
   
   
from sqlalchemy import create_engine
import cv2
import numpy as np
import pandas as pd
import datetime
import time
  • sqlalchemy是連接數據庫(對象關係映射器)的助手,在本例中爲PostgreSQL
  • cv2(開源的計算機視覺庫,或稱爲OpenCV):這個python庫可以幫助從相機中過濾出像素顏色,用於過濾紅色
  • pandas使創建矩陣列和行以將數據保存到數據庫變得更容易
  • datetimetime,管理日期和時間格式的庫
如果發現ModuleNotFoundError錯誤,則應該首先安裝庫

   
   
   
pip install opencv-python
pip install sqlalchemy
pip install pandas
創建連接數據庫的引擎

   
   
   
conn = 
create_engine("postgresql+psycopg2://root:12345678@localhost:5432/plnstats").connect()
我用root用戶名和密碼12345678在本地主機服務器端口5432上創建了名爲plnstats的數據庫
初始化相機並捕獲它。

   
   
   
cap = cv2.VideoCapture(0)
(ret, frame) = cap.read()
cv2.VideoCapture(0),你可以根據計算機視頻設備索引將索引從0更改爲1、2,…等。
cap.read()從相機讀取正確的狀態幀和圖像幀

   
   
   
while True:
(ret, frame) = cap.read()
size = frame.size
image = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

將原始幀轉換爲RGB顏色,image= cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

爲了使用遮罩濾鏡,設置RGB的上下限,我嘗試確定恆定的RGB並應用代碼

   
   
   
lower = np.array([168250])
upper = np.array([179255255])
mask = cv2.inRange(image, lower, upper)
計算紅色與非紅色的百分比

   
   
   
no_red = cv2.countNonZero(mask)
frac_red = np.divide(float(no_red), size)
percent_red = np.multiply((float(frac_red)), 100)
設置閾值,這取決於相機,我使用閾值10.0

   
   
   
if (percent_red >= 10.0):
保存到pd.DataFrame

   
   
   
data_capture = {
'color_percentage': percent_red,
'created_on': datetime.datetime.now()
}
df = pd.DataFrame(columns=['color_percentage','created_on'],data=data_capture,index=[0])
並保存到數據庫中

   
   
   
df.to_sql('home_pln_kwh_sensor', schema='public', con=conn, if_exists='append',index=False)
這是kwh_pln_sensor.py的完整代碼

   
   
   
from sqlalchemy import create_engine
import cv2
import numpy as np
import pandas as pd
import datetime
import time

conn = create_engine("postgresql+psycopg2://root:12345678@localhost:5432/plnstats").connect()

cap = cv2.VideoCapture(0)
(ret, frame) = cap.read()

capture_status = True



while capture_status:
    (ret, frame) = cap.read()

    size = frame.size

    image = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    lower = np.array([168250])
    upper = np.array([179255255])
    mask = cv2.inRange(image, lower, upper)

    no_red = cv2.countNonZero(mask)
    frac_red = np.divide(float(no_red), size)
    percent_red = np.multiply((float(frac_red)), 100)

    print(percent_red)    
    if (percent_red >= 10.0): #estimated from the red colour percentage impulse LED lamp
        data_capture = {
            'color_percentage': percent_red,
            'created_on': datetime.datetime.now()
        }

        df = pd.DataFrame(columns=['color_percentage','created_on'],data=data_capture,index=[0])
        df.to_sql('home_pln_kwh_sensor', schema='public', con=conn, if_exists='append',index=False)

cap.release()
cv2.destroyAllWindows()
可以刪除第31行中的代碼。該語句將幫助你檢查相機是否成功捕捉到LED閃爍

那麼如何總結傳感器捕獲?
我想提取關於小時使用情況和信用卡使用的信息。之後,我就可以估計自己在家的使用情況,並在我的信用卡被清空之前被注意到。

kwh_pln_calculate.py

與前面一樣,導入所需的庫

   
   
   
import pandas as pd
from datetime import datetime,timedelta
from sqlalchemy import create_engine
我用timedelta來得到昨天的日期(你也可以用來計算不同的時間)
創建常量。IMPULSE_KWH = 1000表示每1000個LED閃爍表示1千瓦時,RUPIAH_PER_KWH = 1444.70表示R-1型/TR 1.301-2.200 VA爲1444.70盧比

   
   
   
IMPULSE_KWH = 1000 
RUPIAH_PER_KWH = 1444.70
這一天的值和昨天的值,格式爲年-月-日

   
   
   
now_date = datetime.now().strftime('%Y-%m-%d')
yesterday_date = datetime.now() - timedelta(days=1)
yesterday_date = yesterday_date.strftime('%Y-%m-%d')
連接PostgreSQL數據庫

   
   
   
conn = create_engine("postgresql+psycopg2://root:12345678@localhost:5432/plnstats").connect()
我想總結一下昨天kWh的使用情況

   
   
   
df = pd.read_sql(sql='SELECT color_percentage, created_on from public.home_pln_kwh_sensor where created_on >= \'{yesterday} 00:00:00\' and created_on < \'{currdate} 00:00:00\''.format(yesterday=yesterday_date,currdate=now_date),con=conn)
將created_on列轉換爲pandas datetime

   
   
   
df['created_on'] = pd.to_datetime(df.created_on)
df['created_on'] = df['created_on'].dt.strftime('%Y-%m-%d %H:%M:%S')
規格化數據,其中一秒只有一個LED閃爍

   
   
   
df = df.drop_duplicates(subset=['created_on'])
每小時寫一欄,以獲取更多說明

   
   
   
df['created_on'] = pd.to_datetime(df.created_on)
df['hour'] = df['created_on'].dt.strftime('%H')
df['day'] =  df['created_on'].dt.strftime('%Y-%m-%d')
創建一天的清單以檢查每天的信用卡使用情況

   
   
   
list_day = list(df['day'].unique())
創建一個新的數據幀進行總結

   
   
   
df_summary = pd.DataFrame(columns=['day','hour','sum_impulse','charges_amount'])
計算

   
   
   
for dday in list_day:
list_hour = list(df[df['day'] == str(dday)]['hour'].unique())
for y in list_hour:
wSumKWH = df[(df['day'] == str(dday)) & (df['hour'] == str(y))]
df_summary = df_summary.append({'hour':y,'day':dday,'sum_impulse':wSumKWH.groupby('hour').count()['day'][0],'charges_amount':(wSumKWH.groupby('hour').count()['day'][0])*RUPIAH_PER_KWH/IMPULSE_KWH},ignore_index=True)
df_summary.to_sql('home_pln_kwh_hour', schema='public', con=conn, if_exists='append', index=False)
credit_summary = df_summary[df_summary['day'] == yesterday_date].groupby('day').sum()
credit_summary.to_sql('home_pln_kwh_summary', schema='public', con=conn, if_exists='append', index=True)
你可以在數據庫中查詢摘要,也可以像這樣從數據幀中提取摘要
圖1爲傳感器每小時的分組,圖2爲千瓦時*千瓦時價格計算後的總結
然後,你可以看到每小時的最高價格。
這是kwh_pln_calculate.py的完整代碼

   
   
   
import pandas as pd
from datetime import datetime,timedelta
from sqlalchemy import create_engine

IMPULSE_KWH = 1000 #depends on prepaid meter
RUPIAH_PER_KWH = 1444.70  # R-1/TR 1.301 – 2.200 VA

def run_cron():
    now_date = datetime.now().strftime('%Y-%m-%d')

    yesterday_date = datetime.now() - timedelta(days=1)
    yesterday_date = yesterday_date.strftime('%Y-%m-%d')

    conn = create_engine("postgresql+psycopg2://root:12345678@localhost:5432/plnstats").connect()

    df = pd.read_sql(sql='SELECT color_percentage, created_on from public.home_pln_kwh_sensor where created_on >= \'{yesterday} 00:00:00\' and created_on < \'{currdate} 00:00:00\''.format(yesterday=yesterday_date,currdate=now_date),con=conn)

    df['created_on'] = pd.to_datetime(df.created_on)

    df['created_on'] = df['created_on'].dt.strftime('%Y-%m-%d %H:%M:%S')
    df = df.drop_duplicates(subset=['created_on'])
    df['created_on'] = pd.to_datetime(df.created_on)
    df['hour'] = df['created_on'].dt.strftime('%H')
    df['day'] =  df['created_on'].dt.strftime('%Y-%m-%d')

    list_day = list(df['day'].unique())

    df_summary = pd.DataFrame(columns=['day','hour','sum_impulse','charges_amount'])

    #DETAIL PER HOUR
    for dday in list_day:
        list_hour = list(df[df['day'] == str(dday)]['hour'].unique())
        for y in list_hour:
            wSumKWH = df[(df['day'] == str(dday)) & (df['hour'] == str(y))]
            df_summary = df_summary.append({'hour':y,'day':dday,'sum_impulse':wSumKWH.groupby('hour').count()['day'][0],'charges_amount':(wSumKWH.groupby('hour').count()['day'][0])*RUPIAH_PER_KWH/IMPULSE_KWH},ignore_index=True)

    df_summary.to_sql('home_pln_kwh_hour', schema='public', con=conn, if_exists='append', index=False)
    credit_summary = df_summary[df_summary['day'] == yesterday_date].groupby('day').sum()

    credit_summary.to_sql('home_pln_kwh_summary', schema='public', con=conn, if_exists='append', index=True)


if __name__ == '__main__':
    run_cron()
謝謝你的閱讀,希望你可以用它來衡量每個月的用電量


  
       
       
       
個人微信(如果沒有備註不拉羣!
請註明: 地區+學校/企業+研究方向+暱稱



下載1:何愷明頂會分享


AI算法與圖像處理」公衆號後臺回覆:何愷明,即可下載。總共有6份PDF,涉及 ResNet、Mask RCNN等經典工作的總結分析


下載2:終身受益的編程指南:Google編程風格指南


AI算法與圖像處理」公衆號後臺回覆:c++,即可下載。歷經十年考驗,最權威的編程規範!



     
     
     
下載3 CVPR2021

AI算法與圖像處公衆號後臺回覆: CVPR 即可下載1467篇CVPR 2020論文 和 CVPR 2021 最新論文

點亮 ,告訴大家你也在看



本文分享自微信公衆號 - AI算法與圖像處理(AI_study)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章