윤영준 윤영준 05-20
hls 스트리밍 및 추론 병합을 위한 테스트 및 코드 작성, config 파일들의 디렉토리 및 명명 리펙토링, ITS api 코드 가독성을 위한 변수 이름 및 잘못 하드코딩되어 있는 (도로 타입 변수 지정 불가) 부분 수정.
@9ac7555e925f75ee14efd0e1d1b68faf7e239c09
ITS/api.py
--- ITS/api.py
+++ ITS/api.py
@@ -8,13 +8,13 @@
 from dotenv import load_dotenv
 
 
-def create_url(apiKey, type, cctvType, minX, maxX, minY, maxY, getType="json",
+def create_url(apiKey, roadType, cctvType, minX, maxX, minY, maxY, getType="json",
                baseurl="https://openapi.its.go.kr:9443/cctvInfo"):
     '''
-    국가교통정보센터 예제 실행
+    국가교통정보센터 api 예제 실행 코드, 더 자세한 내용은
     https://www.its.go.kr/opendata/openApiEx?service=cctv 참고
     :param apiKey: ``str`` 국가교통정보센터에서 발급받은 api 키
-    :param type: ``str`` 도로 유형 ('ex' : 고속도로, 'its' : 국도)
+    :param roadType: ``str`` 도로 유형 ('ex' : 고속도로, 'its' : 국도)
     :param cctvType: ``int`` CCTV 유형 (1. 실시간 스트리밍(HLS) / 2. 동영상 파일(m3u8) / 3. 정지 영상(JPEG))
     :param minX: 최소 경도 영역
     :param maxX: 최대 경도 영역
@@ -23,20 +23,34 @@
     :param getType: 출력 결과 형식 ("xml" or "json")
     :return: api 요청 url
     '''
-    assert type != "ex" or "its", 'Error! type should be either "ex" or "its"'
+    assert roadType != "ex" or "its", 'Error! roadType should be either "ex" or "its"'
     assert cctvType != 1 or 2 or 3, 'Error! cctvType should be one of 1, 2, 3!'
     assert getType != "json" or "xml", 'Error! gettype should be either "json" or "xml"!'
 
     return (
         f"{baseurl}?"
         f"apiKey={apiKey}&"
-        f"type={type}&"
+        f"roadType={roadType}&"
         f"cctvType={cctvType}&"
         f"minX={minX}&maxX={maxX}&minY={minY}&maxY={maxY}&"
         f"getType={getType}"
     )
 
-def gather_cctv_list(xmin, xmax, ymin, ymax, intervals, cctvtype):
+def gather_cctv_list(xmin, xmax, ymin, ymax, intervals, roadType, cctvType):
+    '''
+    :param minX: 최소 경도 영역
+    :param maxX: 최대 경도 영역
+    :param minY: 최소 위도 영역
+    :param maxY: 최대 경도 영역
+    :param intervals: api를 통해서 cctv 목록을 불러올때 위경도 격자 간격
+    :param roadType: ``str`` 도로 유형 ('ex' : 고속도로, 'its' : 국도)
+    :param cctvType: ``int`` CCTV 유형 (1. 실시간 스트리밍(HLS) / 2. 동영상 파일(m3u8) / 3. 정지 영상(JPEG))
+    :return: pandas DataFrame 형태로 반환
+            주요 컬럼은 다음과 같음
+            coordx	 coordy   cctvtype	cctvformat	 cctvname	cctvurl
+
+
+    '''
     dotenv = load_dotenv()
     apiKey= os.getenv("ITS_API")
     x_values = np.linspace(xmin, xmax, intervals+1)
@@ -52,7 +66,7 @@
             x_next = x_values[i + 1]
             y_next = y_values[j + 1]
 
-            url = create_url(apiKey, 'its', cctvtype,
+            url = create_url(apiKey, roadType, cctvType,
                              x, x_next, y, y_next)
             response = requests.get(url)
             response_json = json.loads(response.text)
@@ -66,7 +80,7 @@
                 # df.to_csv(f"result/pohang/listofcctv_포항_{x}_{y}.csv", index=False)
             time.sleep(1)
             print(f"{i}, {j}")
-    all_data_df.to_csv(f"result/{xmin}_{xmax}_y{ymin}_{ymax}.csv")
+    # all_data_df.to_csv(f"result/{xmin}_{xmax}_y{ymin}_{ymax}.csv")
     return all_data_df
 
 def get_jpeg(url):
 
ITS_api_test.py (added)
+++ ITS_api_test.py
@@ -0,0 +1,19 @@
+import os
+import pandas as pd
+from ITS.api import gather_cctv_list
+
+df = pd.read_csv("result/129.2_129.3_y35.9_36.07.csv")
+
+name_of_original = df.loc[0]["cctvname"]
+lat = df.loc[0]["coordx"]
+lon = df.loc[0]["coordy"]
+apiKey = os.getenv("ITS_API")
+lat_lon_interval = 0.000001
+api_result = gather_cctv_list(xmin=lat-lat_lon_interval, ymin=lon-lat_lon_interval, xmax=lat+lat_lon_interval, ymax=lon+lat_lon_interval, intervals=1, roadType=1)
+
+name_of_requested = api_result.loc[0]["cctvname"]
+
+if name_of_original == name_of_requested:
+    print("success")
+    print(name_of_original)
+
 
config/cctv_lists.csv (added)
+++ config/cctv_lists.csv
@@ -0,0 +1,0 @@
 
config/hls_streaming_config.py (added)
+++ config/hls_streaming_config.py
@@ -0,0 +1,0 @@
config/yolo_config.py (Renamed from config.py)
--- config.py
+++ config/yolo_config.py
No changes
config/yolo_config.txt (Renamed from yoloseg/config/classes.txt)
--- yoloseg/config/classes.txt
+++ config/yolo_config.txt
No changes
hls_streaming/hls.py
--- hls_streaming/hls.py
+++ hls_streaming/hls.py
@@ -1,3 +1,4 @@
+import parser
 import time
 import av
 import cv2
@@ -72,7 +73,7 @@
                             img_binary = cv2.imencode('.png', self.current_frame)
                             img_binary = img_binary[1].tobytes()
                             self.send_image_to_server(img_binary, self.endpoint)
-                            # cv2.imwrite(f'hls_streaming/captured_frame_/{datetime.now()}_{frame_name}', img)
+                            cv2.imwrite(f'hls_streaming/captured_frame_/{datetime.now()}_{frame_name}', self.current_frame)
                             self.last_capture_time = current_time
                             print(f"Captured {frame_name} at time: {current_time - self.start_time:.2f}s")
                             self.captured_frame_count +=1
@@ -122,7 +123,7 @@
 if __name__ == "__main__":
     capturer = FrameCapturer(
         'http://cctvsec.ktict.co.kr/5545/LFkDslDT81tcSYh3G4306+mcGlLb3yShF9rx2vcPfltwUL4+I950kcBlD15uWm6K0cKCtAMlxsIptMkCDo5lGQiLlARP+SyUloz8vIMNB18=',
-        101, 10
+        101, 10, 5
     )
     t1 = time.time()
     try:
 
hls_streaming/streaming_process.py (added)
+++ hls_streaming/streaming_process.py
@@ -0,0 +1,14 @@
+from ITS.api import gather_cctv_list
+from hls_streaming.hls import FrameCapturer
+
+def refresh_hls_address(lat, lon, lat_lon_interval=0.000001):
+    api_result = gather_cctv_list(xmin=lat-lat_lon_interval, ymin=lon-lat_lon_interval, xmax=lat+lat_lon_interval, ymax=lon+lat_lon_interval, intervals=1, roadType=1)
+    return api_result.loc[0]["cctvurl"]
+
+if __name__ == "__main__":
+    import argparse
+    args = argparse.ArgumentParser
+    args.add_argument("cctv_num", help="index number of cctv, see cctv_list.csv")
+    args = args.parse_args()
+
+    cctv_ind = args.cctv_num
 
inference_endpoint.py (added)
+++ inference_endpoint.py
@@ -0,0 +1,79 @@
+from flask import Flask, request
+from flask_restx import Api, Resource, fields
+import os
+from datetime import datetime
+from yoloseg.inference_ import Inference, overlay_mask
+import cv2
+import time
+
+app = Flask(__name__)
+api = Api(app, version='1.0', title='CCTV Image Upload API',
+          description='A simple API for receiving CCTV images')
+
+# Namespace definition
+ns = api.namespace('cctv', description='CCTV operations')
+
+model_path = 'yoloseg/weight/best.onnx'
+classes_txt_file = 'config/yolo_config.txt'
+image_path = 'yoloseg/img3.jpg'
+
+model_input_shape = (640, 640)
+inference_engine = Inference(
+    onnx_model_path=model_path,
+    model_input_shape=model_input_shape,
+    classes_txt_file=classes_txt_file,
+    run_with_cuda=True
+)
+
+# Define the expected model for incoming data
+image_upload_model = api.model('ImageUpload', {
+    'image': fields.String(required=True, description='Image file', dt='File'),
+    'x-cctv-info': fields.String(required=False, description='CCTV identifier'),
+    'x-time-sent': fields.String(required=False, description='Time image was sent'),
+    'x-cctv-latitude': fields.String(required=False, description='Latitude of CCTV'),
+    'x-cctv-longitude': fields.String(required=False, description='Longitude of CCTV')
+})
+
+# Define the directory where images will be saved
+IMAGE_DIR = "network_test"
+if not os.path.exists(IMAGE_DIR):
+    os.makedirs(IMAGE_DIR)
+
[email protected]('/infer', )
+class ImageUpload(Resource):
+    # @ns.expect(image_upload_model, validate=True)
+    @ns.response(200, 'Success')
+    @ns.response(400, 'Validation Error')
+    def post(self):
+        if 'file' not in request.files:
+            ns.abort(400, 'No image part in the request')
+        image = request.files['file']
+        cctv_info = request.headers.get('x-cctv-info', '')
+        time_sent = request.headers.get('x-time-sent', '')
+        cctv_latitude = request.headers.get('x-cctv-latitude', 'Not provided')
+        cctv_longitude = request.headers.get('x-cctv-longitude', 'Not provided')
+
+        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+        image = cv2.imdecode(image)
+        filename = f"{timestamp}_{cctv_info}.png"
+
+        t1 = time.time()
+        detections, mask_maps = inference_engine.run_inference(image)
+        t2 = time.time()
+
+        if mask_maps is not None:
+            seg_image = overlay_mask(image, mask_maps[0], color=(0, 255, 0), alpha=0.3)
+
+        if image.filename == '':
+            ns.abort(400, 'No selected image')
+
+        # Use current timestamp to avoid filename conflicts
+        # image_path = os.path.join(IMAGE_DIR, filename)
+        # image.save(image_path)
+
+        return {"message": f"Image {filename} uploaded successfully!"}
+
+    def send_result(self):
+        pass
+if __name__ == '__main__':
+    app.run(debug=True, port=12345)
 
run_image_anal_backend.sh (added)
+++ run_image_anal_backend.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# Array to hold the process IDs
+declare -a pids
+
+# Start multiple Python processes in the background
+python hls_streaming/hls.py &
+pids+=($!)
+python hls_streaming/hls.py &
+pids+=($!)
+
+# Function to kill all processes
+cleanup() {
+    echo "Terminating all processes..."
+    for pid in "${pids[@]}"; do
+        kill -9 $pid
+    done
+}
+
+# Trap keyboard interrupt and call cleanup
+trap cleanup SIGINT
+
+# Print message
+echo "Running... Press Ctrl+C to stop."
+
+# Wait forever until Ctrl+C is pressed
+while true; do
+    sleep 1
+done
test.py
--- test.py
+++ test.py
@@ -2,6 +2,7 @@
 from flask_restx import Api, Resource, fields
 import os
 from datetime import datetime
+from yoloseg.inference_ import Inference
 
 app = Flask(__name__)
 api = Api(app, version='1.0', title='CCTV Image Upload API',
@@ -20,7 +21,7 @@
 })
 
 # Define the directory where images will be saved
-IMAGE_DIR = "received_images"
+IMAGE_DIR = "network_test"
 if not os.path.exists(IMAGE_DIR):
     os.makedirs(IMAGE_DIR)
 
yoloseg/inference_.py
--- yoloseg/inference_.py
+++ yoloseg/inference_.py
@@ -188,7 +188,7 @@
 
     # Path to your ONNX model and classes text file
     model_path = 'yoloseg/weight/best.onnx'
-    classes_txt_file = 'yoloseg/config/classes.txt'
+    classes_txt_file = 'yoloseg/config/yolo_config.txt'
     image_path = 'yoloseg/img3.jpg'
 
     model_input_shape = (640, 640)
@@ -241,7 +241,7 @@
 
     # Path to your ONNX model and classes text file
     model_path = 'yoloseg/weight/best.onnx'
-    classes_txt_file = 'yoloseg/config/classes.txt'
+    classes_txt_file = 'yoloseg/config/yolo_config.txt'
 
     model_input_shape = (640, 640)
     inference_engine = Inference(
Add a comment
List