diff --git a/ai_services/vision/python/stream-video/stream-process-output.ipynb b/ai_services/vision/python/stream-video/stream-process-output.ipynb new file mode 100644 index 00000000..43e96523 --- /dev/null +++ b/ai_services/vision/python/stream-video/stream-process-output.ipynb @@ -0,0 +1,192 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "bacae64c", + "metadata": {}, + "outputs": [], + "source": [ + "from oci.object_storage import ObjectStorageClient\n", + "import time\n", + "import base64\n", + "from PIL import Image\n", + "from io import BytesIO\n", + "import cv2\n", + "import numpy as np\n", + "import json\n", + "import oci\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "019e28f5", + "metadata": {}, + "outputs": [], + "source": [ + "NAMESPACE = \"\"\n", + "BUCKET = \"\"\n", + "PREFIX = \"\"\n", + "CONFIG_PROFILE = \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20ecb251", + "metadata": {}, + "outputs": [], + "source": [ + "# Configure OCI client\n", + "config = oci.config.from_file('~/.oci/config', profile_name=CONFIG_PROFILE)\n", + "endpoint = \"https://objectstorage.us-ashburn-1.oraclecloud.com\"\n", + "token_file = config['security_token_file']\n", + "with open(token_file, 'r') as f:\n", + " token = f.read()\n", + "\n", + "private_key = oci.signer.load_private_key_from_file(config['key_file'])\n", + "signer = oci.auth.signers.SecurityTokenSigner(token, private_key)\n", + "object_storage_client = ObjectStorageClient(config=config, signer=signer, service_endpoint=endpoint)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ccf81481", + "metadata": {}, + "outputs": [], + "source": [ + "def decode_image(image_data):\n", + " \"\"\"Decode base64 image to OpenCV format and ensure it has 3 channels (RGB).\"\"\"\n", + " image_bytes = base64.b64decode(image_data)\n", + " image = Image.open(BytesIO(image_bytes))\n", + "\n", + " if image.mode not in (\"RGB\", \"RGBA\"):\n", + " image = image.convert(\"RGB\")\n", + "\n", + " return cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81e8fb29", + "metadata": {}, + "outputs": [], + "source": [ + "def draw_faces(image, faces, frame):\n", + " \"\"\"Draw bounding boxes around detected faces.\"\"\"\n", + " height, width, _ = image.shape\n", + " for face in faces:\n", + " if face['name'] == 'weapon':\n", + " vertices = face['boundingPolygon']['normalizedVertices']\n", + " pts = [(int(v['x'] * width), int(v['y'] * height)) for v in vertices]\n", + " cv2.polylines(image, [np.array(pts)], isClosed=True, color=(0, 255, 0), thickness=2)\n", + " if frame is not None:\n", + " # Add frame number text in the top right corner\n", + " text = f\"Frame: {frame}\"\n", + " font = cv2.FONT_HERSHEY_SIMPLEX\n", + " font_scale = 1\n", + " color = (0, 255, 0)\n", + " thickness = 1\n", + " text_size = cv2.getTextSize(text, font, font_scale, thickness)[0]\n", + " text_x = width - text_size[0] - 10\n", + " text_y = 30\n", + " cv2.putText(image, text, (text_x, text_y), font, font_scale, color, thickness)\n", + "\n", + " return image" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "299aa92f", + "metadata": {}, + "outputs": [], + "source": [ + "def process_and_display(message):\n", + " \"\"\"Process detection data and update the window.\"\"\"\n", + " message = message.replace(\"'\", '\"') # Make it valid JSON\n", + " message_dict = json.loads(message)\n", + "\n", + " image = decode_image(message_dict['imageData'])\n", + " if len(message_dict['detectedObjects']) > 0:\n", + " face_id = message_dict['detectedObjects'][0]['objectId']\n", + " print(\"face detected\", face_id)\n", + "\n", + " print(message_dict['detectedObjects'])\n", + " # Uncomment if you want to visualize\n", + " annotated_image = draw_faces(image, message_dict['detectedObjects'], message_dict[\"imageData\"])\n", + " cv2.imshow(\"Face Detection\", annotated_image)\n", + " cv2.waitKey(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1fafd752", + "metadata": {}, + "outputs": [], + "source": [ + "def main():\n", + " while True:\n", + " ts_ns = int(time.time() * 1_000_000_000) - 3_000_000_000\n", + " filename = f\"new1/frame_{ts_ns}.json\"\n", + "\n", + " objects = object_storage_client.list_objects(\n", + " namespace_name=NAMESPACE,\n", + " bucket_name=BUCKET,\n", + " prefix=PREFIX,\n", + " start_after=filename\n", + " ).data.objects\n", + "\n", + " if objects:\n", + " obj_name = objects[0].name\n", + " resp = object_storage_client.get_object(\n", + " namespace_name=NAMESPACE,\n", + " bucket_name=BUCKET,\n", + " object_name=obj_name\n", + " )\n", + " content = resp.data.content.decode(\"utf-8\")\n", + " process_and_display(content)\n", + " print(f\"File: {obj_name}\")\n", + " # print(content)\n", + "\n", + " time.sleep(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27638749", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " main()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ai_services/vision/python/stream-video/stream-process-output.py b/ai_services/vision/python/stream-video/stream-process-output.py new file mode 100644 index 00000000..6b2bf6cf --- /dev/null +++ b/ai_services/vision/python/stream-video/stream-process-output.py @@ -0,0 +1,109 @@ +import time +import base64 +from PIL import Image +from io import BytesIO +import cv2 +import numpy as np +import json +import oci +from oci.object_storage import ObjectStorageClient + + +NAMESPACE = "" +BUCKET = "" +PREFIX = "" +CONFIG_PROFILE = "" + + +def decode_image(image_data): + """Decode base64 image to OpenCV format and ensure it has 3 channels (RGB).""" + image_bytes = base64.b64decode(image_data) + image = Image.open(BytesIO(image_bytes)) + + if image.mode not in ("RGB", "RGBA"): + image = image.convert("RGB") + + return cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) + + +def process_and_display(message): + """Process detection data and update the window.""" + message = message.replace("'", '"') # Make it valid JSON + message_dict = json.loads(message) + + image = decode_image(message_dict['imageData']) + if len(message_dict['detectedObjects']) > 0: + face_id = message_dict['detectedObjects'][0]['objectId'] + print("face detected", face_id) + + print(message_dict['detectedObjects']) + # Uncomment if you want to visualize + annotated_image = draw_faces(image, message_dict['detectedObjects'], message_dict["imageData"]) + cv2.imshow("Face Detection", annotated_image) + cv2.waitKey(1) + + +def draw_faces(image, faces, frame): + """Draw bounding boxes around detected faces.""" + height, width, _ = image.shape + for face in faces: + if face['name'] == 'weapon': + vertices = face['boundingPolygon']['normalizedVertices'] + pts = [(int(v['x'] * width), int(v['y'] * height)) for v in vertices] + cv2.polylines(image, [np.array(pts)], isClosed=True, color=(0, 255, 0), thickness=2) + if frame is not None: + # Add frame number text in the top right corner + text = f"Frame: {frame}" + font = cv2.FONT_HERSHEY_SIMPLEX + font_scale = 1 + color = (0, 255, 0) + thickness = 1 + text_size = cv2.getTextSize(text, font, font_scale, thickness)[0] + text_x = width - text_size[0] - 10 + text_y = 30 + cv2.putText(image, text, (text_x, text_y), font, font_scale, color, thickness) + + return image + + +def main(): + # Configure OCI client + config = oci.config.from_file('~/.oci/config', profile_name=CONFIG_PROFILE) + oendpoint = "https://objectstorage.us-ashburn-1.oraclecloud.com" + + token_file = config['security_token_file'] + with open(token_file, 'r') as f: + token = f.read() + + private_key = oci.signer.load_private_key_from_file(config['key_file']) + signer = oci.auth.signers.SecurityTokenSigner(token, private_key) + object_storage_client = ObjectStorageClient(config=config, signer=signer, service_endpoint=oendpoint) + + while True: + ts_ns = int(time.time() * 1_000_000_000) - 3_000_000_000 + filename = f"new1/frame_{ts_ns}.json" + + objects = object_storage_client.list_objects( + namespace_name=NAMESPACE, + bucket_name=BUCKET, + prefix=PREFIX, + start_after=filename + ).data.objects + + if objects: + obj_name = objects[0].name + resp = object_storage_client.get_object( + namespace_name=NAMESPACE, + bucket_name=BUCKET, + object_name=obj_name + ) + content = resp.data.content.decode("utf-8") + process_and_display(content) + print(f"File: {obj_name}") + # print(content) + + time.sleep(1) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ai_services/vision/python/stream-video/stream-video.ipynb b/ai_services/vision/python/stream-video/stream-video.ipynb new file mode 100644 index 00000000..930cfbf1 --- /dev/null +++ b/ai_services/vision/python/stream-video/stream-video.ipynb @@ -0,0 +1,316 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "41ad150e", + "metadata": {}, + "outputs": [], + "source": [ + "from oci.ai_vision import AIServiceVisionClient\n", + "from oci.ai_vision.models import VideoFeature, TrackingType, VideoObjectDetectionFeature , CreateStreamJobDetails, CreateStreamSourceDetails, RtspSourceDetails, StreamSourceDetails , StreamGroup,CreateVisionPrivateEndpointDetails, PrivateStreamNetworkAccessDetails , StreamNetworkAccessDetails ,ObjectStorageOutputLocation, UpdateStreamSourceDetails ,UpdateStreamJobDetails , UpdateStreamGroupDetails , UpdateVisionPrivateEndpointDetails , CreateStreamGroupDetails \n", + "\n", + "import oci, time" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d131c918", + "metadata": {}, + "outputs": [], + "source": [ + "#fill the empty values based as these are required input parameters\n", + "CONFIG_PROFILE = \"\"\n", + "COMPARTMENT_ID = \"\"\n", + "STREAM_JOB_DISPLAY_NAME = \"stream-job\"\n", + "SUBNET_ID = \"\"\n", + "CAMERA_URL= \"\"\n", + "NAMESPACE= \"\"\n", + "BUCKET= \"\"\n", + "PREFIX= \"testing\"\n", + "SOURCE_TYPE = \"RTSP\"\n", + "FEATURES = [\n", + " {\n", + " \"featureType\": \"OBJECT_TRACKING\",\n", + "\n", + " \"trackingTypes\":[\n", + " {\n", + " \"objects\": [\"face\"],\n", + " \"maxResults\": 5,\n", + " \"shouldReturnLandmarks\": True,\n", + " }\n", + " ]\n", + " }\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "582ad4f4", + "metadata": {}, + "outputs": [], + "source": [ + "config = oci.config.from_file('~/.oci/config', profile_name=CONFIG_PROFILE)\n", + "endpoint = \"https://vision.aiservice.us-ashburn-1.oci.oraclecloud.com\"\n", + "token_file = config['security_token_file']\n", + "with open(token_file, 'r') as f:\n", + " token = f.read()\n", + "private_key = oci.signer.load_private_key_from_file(config['key_file'])\n", + "signer = oci.auth.signers.SecurityTokenSigner(token, private_key)\n", + "ai_service_vision_client = oci.ai_vision.AIServiceVisionClient(config=config, signer=signer, service_endpoint=endpoint)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da2674cf", + "metadata": {}, + "outputs": [], + "source": [ + "# Create Vision Private Endpoint\n", + "create_vision_private_endpoint_details = CreateVisionPrivateEndpointDetails()\n", + "create_vision_private_endpoint_details.display_name = \"pe\"\n", + "create_vision_private_endpoint_details.subnet_id = SUBNET_ID\n", + "create_vision_private_endpoint_details.compartment_id = COMPARTMENT_ID\n", + "\n", + "create_private_endpoint = ai_service_vision_client.create_vision_private_endpoint(create_vision_private_endpoint_details)\n", + "while True:\n", + " create_private_endpoint_work_request = ai_service_vision_client.get_work_request(create_private_endpoint.headers['opc-work-request-id'])\n", + " if create_private_endpoint_work_request.data.status == 'SUCCEEDED':\n", + " private_endpoint_id = create_private_endpoint_work_request.data.id \n", + " break \n", + " elif create_private_endpoint_work_request.data.status == 'FAILED' :\n", + " SystemExit(\"Error Occured while creating Private Endpoint : %s\", create_private_endpoint_work_request.message)\n", + " break\n", + " time.sleep(45)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9917e412", + "metadata": {}, + "outputs": [], + "source": [ + "# Create Stream Source\n", + "privateStreamNetworkAccessDetails =PrivateStreamNetworkAccessDetails()\n", + "privateStreamNetworkAccessDetails.stream_access_type = \"PRIVATE\"\n", + "privateStreamNetworkAccessDetails.private_endpoint_id = private_endpoint_id\n", + "\n", + "\n", + "stream_source_deatils = RtspSourceDetails()\n", + "stream_source_deatils.camera_url = CAMERA_URL\n", + "stream_source_deatils.stream_network_access_details = privateStreamNetworkAccessDetails\n", + "\n", + "create_stream_source_deatils = CreateStreamSourceDetails()\n", + "create_stream_source_deatils.compartment_id = COMPARTMENT_ID\n", + "create_stream_source_deatils.display_name = \"test-source\"\n", + "create_stream_source_deatils.stream_source_details = stream_source_deatils\n", + "\n", + "create_stream_source_request = ai_service_vision_client.create_stream_source(create_stream_source_deatils)\n", + "createworkrequestid = create_stream_source_request.headers['opc-work-request-id']\n", + "\n", + "while True:\n", + " getworkrequestresponse = ai_service_vision_client.get_work_request(createworkrequestid)\n", + " if getworkrequestresponse.data.status == \"SUCCEEDED\":\n", + " stream_source_id = create_stream_source_request.data.id\n", + " break\n", + " elif getworkrequestresponse.data.status == \"FAILED\" :\n", + " SystemExit(\"Error Occured while creating stream source : %s\", create_stream_source_request.message)\n", + " time.sleep(45)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "96aceca2", + "metadata": {}, + "outputs": [], + "source": [ + "# Create Stream Job\n", + "create_stream_job_details = CreateStreamJobDetails()\n", + "create_stream_job_details.stream_source_id = stream_source_id\n", + "\n", + "# For Object Tracker (Only \"face\" supported as of now) - commend if not required\n", + "create_stream_job_details.features = FEATURES\n", + "\n", + "output_location = ObjectStorageOutputLocation()\n", + "output_location.namespace_name = NAMESPACE\n", + "output_location.bucket_name = BUCKET\n", + "output_location.prefix = PREFIX\n", + "# Choose output location in object storage, make sure you have created the bucket\n", + "create_stream_job_details.stream_output_location = output_location\n", + "\n", + "create_stream_job_details.compartment_id = COMPARTMENT_ID\n", + "create_stream_job_details.display_name = STREAM_JOB_DISPLAY_NAME\n", + "\n", + "\n", + "create_stream_job_request = ai_service_vision_client.create_stream_job(create_stream_job_details=create_stream_job_details)\n", + "\n", + "create_stream_job_workrequestid = create_stream_job_request.headers['opc-work-request-id']\n", + "\n", + "while True:\n", + " get_stream_job_workrequest_response = ai_service_vision_client.get_work_request(create_stream_job_workrequestid)\n", + " if get_stream_job_workrequest_response.data.status == \"SUCCEEDED\":\n", + " stream_job_id = create_stream_job_request.data.id\n", + " break\n", + " elif get_stream_job_workrequest_response.data.status == \"FAILED\":\n", + " SystemExit(\"Error Occured while creating stream job : %s\", create_stream_job_request.message)\n", + " time.sleep(45)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3dae5d96", + "metadata": {}, + "outputs": [], + "source": [ + "# Create Stream Group\n", + "streamOverlap = [stream_source_id]\n", + "create_stream_group_details = CreateStreamGroupDetails()\n", + "create_stream_group_details.compartment_id = COMPARTMENT_ID\n", + "create_stream_group_details.display_name = \"FunctionalityTest2\"\n", + "create_stream_group_details.is_enabled = True\n", + "create_stream_group_details._stream_source_ids = streamOverlap\n", + "\n", + "create_stream_group_request = ai_service_vision_client.create_stream_group(create_stream_group_details)\n", + "\n", + "while True:\n", + " create_streamgroup__work_request = ai_service_vision_client.get_work_request(create_stream_group_request.headers['opc-work-request-id'])\n", + " if getworkrequestresponse.data.status == \"SUCCEEDED\":\n", + " stream_group_id = create_stream_group_request.data.id\n", + " break\n", + " elif create_streamgroup__work_request.data.status == \"FAILED\" :\n", + " SystemExit(\"Error Occured while creating stream group : %s\", create_stream_group_request.message)\n", + " time.sleep(20)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "582c2159", + "metadata": {}, + "outputs": [], + "source": [ + "# Start Stream Job\n", + "start_stream_job_request = ai_service_vision_client.start_stream_job(stream_job_id)\n", + "\n", + "while True:\n", + " start_stream_job_work_request = ai_service_vision_client.get_work_request(start_stream_job_request.headers['opc-work-request-id'])\n", + " if start_stream_job_work_request.data.status == 'SUCCEEDED':\n", + " ##success \n", + " break\n", + " elif start_stream_job_work_request.data.status == 'FAILED' :\n", + " SystemExit(\"Error Occured while starting stream job : %s\", start_stream_job_request.message)\n", + " time.sleep(45)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00b1cbd1", + "metadata": {}, + "outputs": [], + "source": [ + "# Stop Stream Job\n", + "stop_stream_job_request = ai_service_vision_client.stop_stream_job(stream_job_id)\n", + "\n", + "while True:\n", + " stop_stream_job_work_request = ai_service_vision_client.get_work_request(stop_stream_job_request.headers['opc-work-request-id'])\n", + " if stop_stream_job_work_request.data.status == 'SUCCEEDED':\n", + " break\n", + " elif stop_stream_job_work_request.data.status == 'FAILED':\n", + " SystemExit(\"Error occured while stoping stream job : %s\", stop_stream_job_request.message)\n", + " time.sleep(45)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c11aa077", + "metadata": {}, + "outputs": [], + "source": [ + "# delete_stream_group\n", + "stream_group_delete_request = ai_service_vision_client.delete_stream_group(stream_group_id)\n", + "\n", + "while True:\n", + " stream_group_delete_work_request = ai_service_vision_client.get_work_request(stream_group_delete_request.headers['opc-work-request-id'])\n", + " if stream_group_delete_work_request.data.status == 'SUCCEEDED' :\n", + " break\n", + " elif stream_group_delete_work_request.data.status == 'FAILED' :\n", + " SystemExit(\"Error occured while deleting stream group : %s\", stream_group_delete_request.message)\n", + " time.sleep(20)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d3ba307f", + "metadata": {}, + "outputs": [], + "source": [ + "# delete_stream_job\n", + "stream_job_delete_request = ai_service_vision_client.delete_stream_job(stream_job_id)\n", + "\n", + "while True:\n", + " stream_job_delete_work_request = ai_service_vision_client.get_work_request(stream_job_delete_request.headers['opc-work-request-id'])\n", + " if stream_job_delete_work_request.data.status == 'SUCCEEDED':\n", + " break\n", + " elif stream_job_delete_work_request.data.status == 'FAILED' :\n", + " SystemExit(\"Error occured while deleting stream job : %s\", stream_job_delete_request.message)\n", + " time.sleep(30)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61940e82", + "metadata": {}, + "outputs": [], + "source": [ + "# delete_stream_source\n", + "delete_stream_source_request = ai_service_vision_client.delete_stream_source(stream_source_id)\n", + "\n", + "while True:\n", + " delete_stream_source_work_request = ai_service_vision_client.get_work_request(delete_stream_source_request.headers['opc-work-request-id'])\n", + " print(delete_stream_source_work_request.data.status)\n", + " if delete_stream_source_work_request.data.status == 'SUCCEEDED':\n", + " break\n", + " elif delete_stream_source_work_request.data.status == 'FAILED' :\n", + " SystemExit(\"Error occured while deleting stream source : %s\", delete_stream_source_request.message)\n", + " time.sleep(20)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26059d30", + "metadata": {}, + "outputs": [], + "source": [ + "# delete vision private endpoint\n", + "delete_private_endpoint_request = ai_service_vision_client.delete_vision_private_endpoint(private_endpoint_id)\n", + "\n", + "while True:\n", + " delete_private_endpoint_work_request = ai_service_vision_client.get_work_request(delete_private_endpoint_request.headers['opc-work-request-id'])\n", + " if delete_private_endpoint_work_request.data.status == 'SUCCEEDED' :\n", + " break\n", + " elif delete_private_endpoint_work_request.data.status == 'FAILED' :\n", + " SystemExit(\"Error occured while deleting private endpoint : %s\", delete_private_endpoint_request.message)\n", + "\n", + " time.sleep(120)" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}