C#

    # worker.py
    import sys
    import json
    import struct
    import traceback
    import numpy as np


    def read_exact(stream, size: int) -> bytes:
        """
        指定byte数を必ず読む。
        足りない場合はEOF扱い。
        """
        data = bytearray()

        while len(data) < size:
            chunk = stream.read(size - len(data))
            if not chunk:
                raise EOFError("stdin closed while reading data")
            data.extend(chunk)

        return bytes(data)


    def read_packet():
        """
        C#から送られてくる1パケットを読む。
        形式:
        4byte: JSONヘッダ長 little-endian uint32
        Nbyte: JSONヘッダ
        Mbyte: 画像データ
        """
        # 4byteのヘッダ長を読む
        header_len_bytes = read_exact(sys.stdin.buffer, 4)
        header_len = struct.unpack("<I", header_len_bytes)[0]

        # JSONヘッダを読む
        header_json = read_exact(sys.stdin.buffer, header_len).decode("utf-8")
        header = json.loads(header_json)

        # 画像本体を読む
        byte_length = int(header["byte_length"])
        image_bytes = read_exact(sys.stdin.buffer, byte_length)

        return header, image_bytes


    def write_packet(header: dict, image_bytes: bytes):
        """
        C#へ1パケット返す。
        """
        header_json = json.dumps(header, ensure_ascii=False).encode("utf-8")
        header_len_bytes = struct.pack("<I", len(header_json))

        sys.stdout.buffer.write(header_len_bytes)
        sys.stdout.buffer.write(header_json)
        sys.stdout.buffer.write(image_bytes)
        sys.stdout.buffer.flush()


    def process_image_dummy(header: dict, image_bytes: bytes):
        """
        ダミー処理。
        受け取ったMono8画像をnumpy配列にして、
        今回は何もせずそのまま返す。
        """
        width = int(header["width"])
        height = int(header["height"])
        pixel_type = header["pixel_type"]

        if pixel_type != "mono8":
            raise ValueError(f"Unsupported pixel_type: {pixel_type}")

        expected_len = width * height
        if len(image_bytes) != expected_len:
            raise ValueError(
                f"Invalid image size. expected={expected_len}, actual={len(image_bytes)}"
            )

        # byte列 → numpy画像
        img = np.frombuffer(image_bytes, dtype=np.uint8).reshape((height, width))


        # 例:
        # processed = cv2.GaussianBlur(img, (3, 3), 0)
        #
        # 今回はダミーなのでそのまま返す
        processed = img

        # numpy画像 → byte列
        result_bytes = processed.tobytes()

        result_header = {
            "frame_id": header.get("frame_id"),
            "ok": True,
            "width": width,
            "height": height,
            "pixel_type": "mono8",
            "byte_length": len(result_bytes),
            "message": "dummy passthrough"
        }

        return result_header, result_bytes


    def main():
        # 重要:
        # stdoutはC#へのバイナリ応答専用。
        # ログは必ずstderrへ出す。
        print("Python worker started", file=sys.stderr, flush=True)

        while True:
            try:
                header, image_bytes = read_packet()
                result_header, result_bytes = process_image_dummy(header, image_bytes)
                write_packet(result_header, result_bytes)

            except EOFError:
                print("stdin closed. worker exiting.", file=sys.stderr, flush=True)
                break

            except Exception as e:
                # エラー時もC#が読めるように、エラーパケットを返す
                print("Error occurred:", file=sys.stderr, flush=True)
                print(traceback.format_exc(), file=sys.stderr, flush=True)

                error_header = {
                    "frame_id": None,
                    "ok": False,
                    "width": 0,
                    "height": 0,
                    "pixel_type": "mono8",
                    "byte_length": 0,
                    "message": str(e)
                }

                write_packet(error_header, b"")


    if __name__ == "__main__":
        main()



    # ------


    # worker.py
    import sys
    import json
    import struct
    import traceback
    import numpy as np


    def read_exact(stream, size: int) -> bytes:
        data = bytearray()

        while len(data) < size:
            chunk = stream.read(size - len(data))
            if not chunk:
                raise EOFError("stdin closed while reading data")
            data.extend(chunk)

        return bytes(data)


    def read_packet():
        header_len_bytes = read_exact(sys.stdin.buffer, 4)
        header_len = struct.unpack("<I", header_len_bytes)[0]

        header_json = read_exact(sys.stdin.buffer, header_len).decode("utf-8")
        header = json.loads(header_json)

        byte_length = int(header["byte_length"])
        image_bytes = read_exact(sys.stdin.buffer, byte_length)

        return header, image_bytes


    def write_packet(header: dict, image_bytes: bytes):
        header_json = json.dumps(header, ensure_ascii=False).encode("utf-8")
        header_len_bytes = struct.pack("<I", len(header_json))

        sys.stdout.buffer.write(header_len_bytes)
        sys.stdout.buffer.write(header_json)
        sys.stdout.buffer.write(image_bytes)
        sys.stdout.buffer.flush()


    def process_image_dummy(header: dict, image_bytes: bytes):
        width = int(header["width"])
        height = int(header["height"])
        pixel_type = header["pixel_type"]

        if pixel_type != "mono8":
            raise ValueError(f"Unsupported pixel_type: {pixel_type}")

        expected_len = width * height
        if len(image_bytes) != expected_len:
            raise ValueError(
                f"Invalid image size. expected={expected_len}, actual={len(image_bytes)}"
            )

        img = np.frombuffer(image_bytes, dtype=np.uint8).reshape((height, width))

        # ==============================
        # ここに本来のPython画像処理を書く
        # 今回はダミーなのでそのまま返す
        # ==============================
        processed = img

        result_bytes = processed.astype(np.uint8).tobytes()

        result_header = {
            "frame_id": header.get("frame_id"),
            "ok": True,
            "width": width,
            "height": height,
            "pixel_type": "mono8",
            "byte_length": len(result_bytes),
            "message": "dummy passthrough"
        }

        return result_header, result_bytes


    def main():
        print("Python worker started", file=sys.stderr, flush=True)

        while True:
            try:
                header, image_bytes = read_packet()
                result_header, result_bytes = process_image_dummy(header, image_bytes)
                write_packet(result_header, result_bytes)

            except EOFError:
                print("stdin closed. worker exiting.", file=sys.stderr, flush=True)
                break

            except Exception as e:
                print("Error occurred:", file=sys.stderr, flush=True)
                print(traceback.format_exc(), file=sys.stderr, flush=True)

                error_header = {
                    "frame_id": None,
                    "ok": False,
                    "width": 0,
                    "height": 0,
                    "pixel_type": "mono8",
                    "byte_length": 0,
                    "message": str(e)
                }

                write_packet(error_header, b"")


    if __name__ == "__main__":
        main()