MediaPipe Python çerçevesi, Google Cloud'un temel bileşenlerine Timestamp, Packet ve CalculatorGraph gibi MediaPipe C++ çerçevesini kullanıma hazır Python çözümleri ise çerçevenin teknik ayrıntılarını inceler ve okunabilir modeli döndürür. arayanlara döner.
MediaPipe çerçevesi, pybind11 kitaplığı hakkında daha fazla bilgi edinin. C++ temel çerçevesi, Python'da bir C++/Python dil bağlamasıyla kullanıma sunulur. Aşağıdaki içerikte, okuyucunun Arkadaş Bitkiler projesinin oldukça önemlidir. Aksi takdirde, şurada yararlı bilgiler bulabilirsiniz: Çerçeve Çalışması Kavramları.
Paket
Paket, MediaPipe'teki temel veri akışı birimidir. Paket,
bir sayısal zaman damgası ve sabit bir yüke işaret eden paylaşımlı bir işaretçi içerir. Python'da,
MediaPipe paketi,
"the"
mp.packet_creator
modülünü kullanabilirsiniz. Buna karşılık, paket yükü
paket alıcı yöntemlerinin
mp.packet_getter
modülünü kullanabilirsiniz. Paket yükünün paketten sonra değişmez hale geleceğini unutmayın
çok önemli. Bu nedenle, alınan paket içeriğinin değiştirilmesi,
yük olduğunu gösterir. MediaPipe çerçevesi Python API,
MediaPipe'in en yaygın kullanılan veri türleri (ör. ImageFrame, Matris, Protokol
arabellekler ve temel veri türleri) eklemeniz gerekir. Kapsamlı
Aşağıdaki tabloda, Python ile C++ veri türü arasındaki tür eşlemeleri gösterilmektedir
ve her bir veri türü için paket oluşturucu ve içerik alıcı yöntemi ile birlikte
tarafından desteklenir.
Python Veri Türü | C++ Veri Türü | Paket oluşturucu | İçerik Alıcısı |
---|---|---|---|
bool | bool | create_bool(True) | get_bool(packet) |
int veya np.intc | int_t | create_int(1) | get_int(packet) |
int veya np.int8 | int8_t | create_int8(2**7-1) | get_int(packet) |
int veya np.int16 | int16_t | create_int16(2**15-1) | get_int(packet) |
int veya np.int32 | tam32_t | create_int32(2**31-1) | get_int(packet) |
int veya np.int64 | int64_t | create_int64(2**63-1) | get_int(packet) |
int veya np.uint8 | uint8_t | create_uint8(2**8-1) | get_uint(packet) |
int veya np.uint16 | uint16_t | create_uint16(2**16-1) | get_uint(packet) |
int veya np.uint32 | uint32_t | create_uint32(2**32-1) | get_uint(packet) |
int veya np.uint64 | uint64_t | create_uint64(2**64-1) | get_uint(packet) |
kayan veya np.float32 | kayan noktalı | create_float(1.1) | get_float(packet) |
float veya np.double | double | create_double(1.1) | get_float(packet) |
str (UTF-8) | std::string | create_string('abc') | get_str(packet) |
bayt | std::string | create_string(b'\xd0\xd0\xd0') | get_bytes(packet) |
mp.Packet | mp::Packet | create_packet(p) | get_packet(packet) |
Liste[bool] | std::vector<bool> | create_bool_vector([Doğru, Yanlış]) | get_bool_list(packet) |
List[int] veya List[np.intc] | int[] | create_int_array([1; 2; 3]) | get_int_list(paket; size=10) |
List[int] veya List[np.intc] | std::vector<int> | create_int_vector([1, 2, 3]) | get_int_list(packet) |
List[float] veya List[np.float] | float[] | create_float_arrary([0,1; 0,2]) | get_float_list(paket; size=10) |
List[float] veya List[np.float] | std::vector<float> | create_float_vector([0,1, 0,2]) | get_float_list(paket; size=10) |
Liste[str] | std::vector<std::string> | create_string_vector(['a']) | get_str_list(packet) |
Liste[mp.Packet] | std::vector<mp::Packet> | create_packet_vector( [paket1, paket2]) |
get_packet_list(p) |
Eşleme[str, Paket] | std::map<std::string, paket=""></std::string,> | create_string_to_packet_map( {'a': packet1, 'b': packet2}) |
get_str_to_packet_dict(packet) |
np.ndarray (cv.mat ve PIL.Image) |
mp::ImageFrame | create_image_frame( format=ImageFormat.SRGB, data=mat) |
get_image_frame(packet) |
np.ndarray | mp::Matrix | create_matrix(data) | get_matrix(packet) |
Google Proto Mesajı | Google Proto Mesajı | create_proto(proto) | get_proto(packet) |
Liste[Proto] | std::vector<Proto> | Yok | get_proto_list(packet) |
Kullanıcıların özel C++ sınıfları oluşturması ve bunları grafikler ve hesaplayıcılar. Python'da özel sınıfların kullanılmasına izin vermek için kullanıyorsanız, Paket API'yi mevcut bir veri türü için şu adımları uygulayın:
pybind11'i yazma sınıf bağlama kodu veya özel türde bir oynatıcı cc dosyasında da kullanabilirsiniz.
#include "path/to/my_type/header/file.h" #include "pybind11/pybind11.h" namespace py = pybind11; PYBIND11_MODULE(my_type_binding, m) { // Write binding code or a custom type caster for MyType. py::class_<MyType>(m, "MyType") .def(py::init<>()) .def(...); }
ayrı cc dosyası.
#include "path/to/my_type/header/file.h" #include "mediapipe/framework/packet.h" #include "pybind11/pybind11.h" namespace mediapipe { namespace py = pybind11; PYBIND11_MODULE(my_packet_methods, m) { m.def( "create_my_type", [](const MyType& my_type) { return MakePacket<MyType>(my_type); }); m.def( "get_my_type", [](const Packet& packet) { if(!packet.ValidateAsType<MyType>().ok()) { PyErr_SetString(PyExc_ValueError, "Packet data type mismatch."); return py::error_already_set(); } return packet.Get<MyType>(); }); } } // namespace mediapipe
Özel tür bağlama ve yeni paket için iki bazel derleme kuralı ekleyin yöntemleri vardır.
load("@pybind11_bazel//:build_defs.bzl", "pybind_extension") pybind_extension( name = "my_type_binding", srcs = ["my_type_binding.cc"], deps = [":my_type"], ) pybind_extension( name = "my_packet_methods", srcs = ["my_packet_methods.cc"], deps = [ ":my_type", "//mediapipe/framework:packet" ], )
Bazel tarafından oluşturulan pybind uzantı hedeflerini (.so son ekiyle) oluşturun ve oluşturulan dinamik kitaplıkları $LD_LIBRARY_PATH dizinlerinden birine taşıyın.
Python'da bağlama modüllerini kullanın.
import my_type_binding import my_packet_methods packet = my_packet_methods.create_my_type(my_type_binding.MyType()) my_type = my_packet_methods.get_my_type(packet)
Zaman damgası
Her paket, mikrosaniye cinsinden bir zaman damgası içerir. Python'da,
Paket API'si, sayısal değeri tanımlamak için packet.at()
kolaylık yöntemi sunar
zaman damgasıdır. Daha genel olarak, packet.timestamp
paket sınıfıdır
özelliğini kullanmanızı öneririz. Unix dönemini
MediaPipe zaman damgası
Timestamp API'si
bu amaç için bir mp.Timestamp.from_seconds()
yöntemi sunar.
ImageFrame
ImageFrame, görüntülerin veya video karelerinin depolandığı kapsayıcıdır. Biçimler
ImageFrame tarafından desteklenenler şurada listelenmiştir:
ImageFormat sıralaması.
Pikseller, boşluk eklenen renk bileşenleri ve ImageFrame ile satır-ana şeklinde kodlanır
uint8, uint16 ve float'ı destekler. MediaPipe,
ImageFrame Python API
ImageFrame C++ sınıfına erişmek için gereklidir. Python'da, komut dosyasını almanın en kolay yolu
piksel verisi, numpy ndarray elde etmek için image_frame.numpy_view()
işlevini çağırmaktır. Not
dahili piksel verilerine referans olarak döndürülen numpy ndarray
yazılamaz. Arayanların numpy ndarray'i değiştirmesi gerekiyorsa
bir kopyasını almak için kopyalama işlemini açıkça çağırmalıdır. MediaPipe bir numara aldığında
bir ImageFrame oluşturmak için verilerin ardışık olarak depolandığını varsayar.
Buna karşılık, ImageFrame'in piksel verileri, yeni bir resim
tekrarlandığından emin olur.
Grafik
MediaPipe Çerçevesi'nde tüm işleme, Hesap Makinesi Grafiği. HesaplayıcıGraph Python API , C++ CalculatorGraph sınıfı için doğrudan bir bağlayıcıdır. Aradaki en önemli fark hesaplayıcıGraph Python API, JavaScript hatası döndürüyor ve "sorunsuz" durumuna sahip olmayan bir hata oluştuğunda durumu. Bu nedenle, Python kullanıcısı olarak, her zaman olduğu gibi kullanın. Bir hesaplayıcıGrafiği'nin yaşam döngüsü, üç aşama: başlatma ve kurulum, grafik çalıştırma ve grafik kapatma.
hesaplayıcıGraphConfig protobuf veya ikili program ile bir CalculatorGraph'i başlatma protobuf dosyası oluşturabilir ve çıkışı gözlemlemek için geri çağırma yöntemleri sunabilirsiniz. akışlar.
1. Seçenek: Hesap MakinesiGraphConfig protobuf'u kullanarak CalculatorGraph'i başlatma veya metin temsilini inceleyin ve çıkış akışlarını gözlemleyin:
import mediapipe as mp config_text = """ input_stream: 'in_stream' output_stream: 'out_stream' node { calculator: 'PassThroughCalculator' input_stream: 'in_stream' output_stream: 'out_stream' } """ graph = mp.CalculatorGraph(graph_config=config_text) output_packets = [] graph.observe_output_stream( 'out_stream', lambda stream_name, packet: output_packets.append(mp.packet_getter.get_str(packet)))
2. Seçenek İkili protobuf dosyasıyla bir CalculatorGraph'i başlatmak ve çıkış akışlarını gözlemleyin.
import mediapipe as mp # resources dependency graph = mp.CalculatorGraph( binary_graph=os.path.join( resources.GetRunfilesDir(), 'path/to/your/graph.binarypb')) graph.observe_output_stream( 'out_stream', lambda stream_name, packet: print(f'Get {packet} from {stream_name}'))
Grafik çalıştırmayı başlatın ve paketleri grafiğe aktarın.
graph.start_run() graph.add_packet_to_input_stream( 'in_stream', mp.packet_creator.create_string('abc').at(0)) rgb_img = cv2.cvtColor(cv2.imread('/path/to/your/image.png'), cv2.COLOR_BGR2RGB) graph.add_packet_to_input_stream( 'in_stream', mp.packet_creator.create_image_frame(image_format=mp.ImageFormat.SRGB, data=rgb_img).at(1))
Sonlandıktan sonra grafiği kapatın. Başka bir grafik için grafiği yeniden başlatabilirsiniz
close()
çağrısından sonra çalıştırılır.graph.close()
Python komut dosyası, yerel Python çalışma zamanınız tarafından çalıştırılabilir.