s470623-wko/wko-06.ipynb

813 lines
1.1 MiB
Plaintext
Raw Normal View History

2022-11-27 19:15:49 +01:00
{
"cells": [
{
"cell_type": "markdown",
"id": "819ce420",
"metadata": {},
"source": [
"![Logo 1](img/aitech-logotyp-1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Widzenie komputerowe </h1>\n",
"<h2> 06. <i>Rozpoznawanie i segmentacja obrazów</i> [laboratoria]</h2> \n",
"<h3>Andrzej Wójtowicz (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](img/aitech-logotyp-2.jpg)"
]
},
{
"cell_type": "markdown",
"id": "a6dc5acc",
"metadata": {},
"source": [
"W poniższych materiałach zobaczymy w jaki sposób możemy klasycznym podejściem rozpoznawać ludzi na zdjęciach, a ponadto w jaki sposób szybko podzielić obraz na elementy znajdujące się na pierwszym planie i w tle obrazu.\n",
"\n",
"Na początku załadujmy niezbędne biblioteki."
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 1,
2022-11-27 19:15:49 +01:00
"id": "e45bb312",
"metadata": {},
"outputs": [],
"source": [
"import cv2 as cv\n",
"import numpy as np\n",
"import sklearn.svm\n",
"import sklearn.metrics\n",
"import matplotlib.pyplot as plt\n",
"%matplotlib inline\n",
"import os\n",
"import random"
]
},
{
"cell_type": "markdown",
"id": "5b757675",
"metadata": {},
"source": [
"Naszym głównym celem będzie rozpoznawanie ludzi na zdjęciach przy pomocy klasycznej metody *histogram of oriented gradients* (HOG). Krótko mówiąc, dla danego zdjęcia chcemy uzyskać wektor cech, który będziemy mogli wykorzystać w klasyfikatorze SVM. Szczegóły znajdują się w *6.3.2 Pedestrian detection* R. Szeliski (2022) *Computer Vision: Algorithms and Applications*, natomiast tutaj zobrazujemy techniczne wykorzystanie tej metody.\n",
"\n",
"# Klasyfikacja obrazów przy użyciu HOG i SVM\n",
"\n",
"Spróbjemy zbudować klasyfikator, który wskazuje czy na zdjęciu znajduje się osoba z okularami czy bez okularów. Rozpakujmy zbiór danych, z którego będziemy korzystali:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 4,
2022-11-27 19:15:49 +01:00
"id": "7b953b82",
"metadata": {},
"outputs": [],
"source": [
"!cd datasets && unzip -qo glasses.zip"
]
},
{
"cell_type": "markdown",
"id": "f4a457f3",
"metadata": {},
"source": [
"Następnie wczytujemy dane i dzielimy je na dwa zbiory w proporcjach 80/20:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 5,
2022-11-27 19:15:49 +01:00
"id": "737d95c1",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train data: 1272, test data: 319\n"
]
}
],
2022-11-27 19:15:49 +01:00
"source": [
"dataset_dir = \"datasets/glasses\"\n",
"images_0 = os.listdir(f\"{dataset_dir}/with\")\n",
"images_0 = [f\"{dataset_dir}/with/{x}\" for x in images_0]\n",
"images_1 = os.listdir(f\"{dataset_dir}/without\")\n",
"images_1 = [f\"{dataset_dir}/without/{x}\" for x in images_1]\n",
"images = images_0 + images_1\n",
"random.seed(1337)\n",
"random.shuffle(images)\n",
"\n",
"train_data = []\n",
"test_data = []\n",
"train_labels = []\n",
"test_labels = []\n",
"\n",
"splitval = int((1-0.2)*len(images))\n",
"\n",
"for x in images[:splitval]:\n",
" train_data.append(cv.imread(x, cv.IMREAD_COLOR))\n",
" train_labels.append(x.split(\"/\")[2])\n",
" \n",
"for x in images[splitval:]:\n",
" test_data.append(cv.imread(x, cv.IMREAD_COLOR))\n",
" test_labels.append(x.split(\"/\")[2])\n",
" \n",
"d_labels = {\"with\": 0, \"without\": 1}\n",
" \n",
"train_labels = np.array([d_labels[x] for x in train_labels])\n",
"test_labels = np.array([d_labels[x] for x in test_labels])\n",
"\n",
"print(f\"Train data: {len(train_data)}, test data: {len(test_data)}\")"
]
},
{
"cell_type": "markdown",
"id": "265147e3",
"metadata": {},
"source": [
"Poniżej znajduje się kilka przykładowych zdjęć."
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 6,
2022-11-27 19:15:49 +01:00
"id": "e0595915",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAzYAAABdCAYAAAB3lPNFAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAAD1X0lEQVR4nOz9WYymaXbfif2e7V2/LbaMzKzMWru7qheym8Nmt7YZG5I8nLFgSzMCRrAxBkeAL6UbGoZF2JCgK10YMARYgn3hK19ZA2M8ljAejkakSEk0KbK7SfZa1V1ZWVm5xvrt37s8my+eN6JaJjQqQt3ZpBCnkV1VkZGREd933uc553/+//8RMcbITdzETdzETdzETdzETdzETdzEH+OQP+lv4CZu4iZu4iZu4iZu4iZu4iZu4t82bhqbm7iJm7iJm7iJm7iJm7iJm/hjHzeNzU3cxE3cxE3cxE3cxE3cxE38sY+bxuYmbuImbuImbuImbuImbuIm/tjHTWNzEzdxEzdxEzdxEzdxEzdxE3/s46axuYmbuImbuImbuImbuImbuIk/9nHT2NzETdzETdzETdzETdzETdzEH/u4aWxu4iZu4iZu4iZu4iZu4iZu4o993DQ2N3ETN3ETN3ETN3ETN3ETN/HHPm4am5u4iZu4iZu4iZu4iZu4iZv4Yx8/tsbm7//9v8/rr79OURR89atf5bd/+7d/XH/VTdzEH4ib/LuJn2Tc5N9N/KTjJgdv4icZN/l3Ez+p+LE0Nv/gH/wDfvEXf5G/9bf+Ft/4xjf44he/yM///M9zenr64/jrbuIm/pW4yb+b+EnGTf7dxE86bnLwJn6ScZN/N/GTDBFjjD/qL/rVr36Vn/u5n+Pv/b2/B0AIgfv37/PX//pf52/8jb/xo/7rbuIm/pW4yb+b+EnGTf7dxE86bnLwJn6ScZN/N/GTDP2j/oJ93/P1r3+dX/qlX7r+mJSSP//n/zy/+Zu/+Qc+v+s6uq67/u8QApeXlxwcHCCE+FF/ezfxxzRijKzXa+7evYuU//pB4x82/+AmB2/i3xw3+XcTP+n4ceXgTf7dxCeJmzPwJn6S8UnzD34Mjc35+Tnee46Pj/+Vjx8fH/Puu+/+gc//O3/n7/C3//bf/lF/Gzfx72g8fvyYe/fu/Wt//w+bf3CTgzfxyeMm/27iJx0/6hy8yb+b+MPEzRl4Ez/J+DflH/wYGps/bPzSL/0Sv/iLv3j938vlkldffZW3X79NmWVUecbn336b11+7x6fefIPXXr2HdQ3OW0KwCKkAsL3lV//7X+fiYk4McOvWMftHh3jv6Z1l//CAvrc46+it5ezkhPF4zHg84t3vfI8sz6jqmv2DA5q2pbc9PsKd27c5OzsBIvt7e5RGkxmNVgotoMgytBIIJRmPRhhjEFLhrEXnGVJJpIAiz5FSgAAhIMaAVIrM5Ox2LUiJUoa8qNk/uk3fd8wvzol2A9EjJBRZQQg+fQ0EIYD3nhgjQkqqagSI9DlREgXECDFEUBIQEMD5HikiwTnapiNKgQsR5wNlXWC9o21blqsFdVWihMJZz7vf+z5lNcFkBVJn/NNf++fYGJjMZvxHf+F/yte+9jUuLy4RLmC0xHY91nYEbzk8PKQoC7SSdG3Her2m2e0gRO6/9hqbzYYPPviQ1998g+n+Hke3bvGVP/EnCARMnhNC5Itf+fOMx+OXloP/8Vc/y/H+jLv7MyZVzqjKmYxK8jzj7t075HnBsxfPMEIRQ8AFi+s6dKbRWmEyTZbnaKlRSAKRLC9BSqx3lFWZ3pMYEdoQY6DvPbvtjsPDQ2KIeG+JIaJMjhxyXSiJ844YIlVdglT44f2ryhEiQiQSQrhGNmKMGJPhnE05I0Cr9Pj74EEIjNJIKXHOoaUixvQ1nO8RIqa8BYxU6ePOIaVECoEUEiEEUmiCd1jXI4LAOYvzDusdQgiEFAghyYxit91gO4t3nrIq8M7Rd5beOqbTMVmWAYLzi3Os7bHOs16vcM6R5xl7+/s8e/4C59LXHo1GGG3w3tHsdsznc9q2xcdAXY9o+w7vPDEGSpNTlQWFMSgZKOsyPddGs902NK3FBshHU/773/wtnpxd8o9/8/2Xmn9loSEEpA186o377E1qJqOKO7cOWSwvsG1LWeZMxjXjumRcVygh6dodUgoODw7xRLTW6CxDGUWVlygp8c4yHU3IjEFlBpVrhBCYLGc8mSKFwugMrTUighASISU6M/TWIpVASYGIgcRmFgipCD4y/AHyLIeQfj/EiAsx5YCQSCnxIf05KQQxhpRfIhKDRw5nHEQ6byFCCBHXWYIP9Lanaxt629M0O2zX4V0PPqZHSgiCVKxWK2zfoYVmMpkQEQRgdnDA7PA2WZbTWUuRKZrdlvV6Tdc0ZMOZs9rsyPOcGDzBWVzfUJU5Rst0pAbIspw8L5lMpiilQKTvPDOaSGJ6CwQhBmIMRNLzKcQVC1wQQkznQIC27dhsG7ZtR9M5/p//8L/m+w8+4NFHz/hwHn7kOfivy7+/8LkZuVEYXdD1LX1n6foOKRV5lqOUIhKIPiIFZJnmrdde4/j2McTAe++9y2w24eBgn8ODA+qqwPke5z1939N0DVpLlNY02y3b1Yo8M7x27z7zi3l6/6NgtdkwmkyJUrFre2wfOD875/JygRQapQ1KKZRWlEUJ3gMwnUxpmpQj1jkmsylSKaSUmEwhQsAoRWkyhPdMxiOKsgABZZGjtUQM93xuDMZo8swM+Z5+ZiUFPnoiIFFExPX9LKW6njaEkPJbpN9Okb5M+r0hR9LzIYgxEmMgBE8gpudPSKKI9M7hgyf6gB/OPilIORoDIYANgRjTgZ2+NhAjPgR8CLjh+4kx0nUdAUGMEFxg21h653A+0LjAcrtlvdpwcnHJ//1rH77UM/A/+9M/S2kyRmVNZjSX8zlPn7+gHtXkZYELgdPTEz7/uc8zGY3Jc4OQgrIoMZlBG02uDYXOqbOMoihwMSCEpChznPUoLVFKsds2w3MpUVJTFDlKaZTSqXbRBqkkQip8/Pi5lkJdf99KCKQSxJD+O8sM1tn0uSp9ng+eGCHLc3pnh3zM0Npc50WIEWM0PgSsDygUWhmkUiij8Namc0YKYgh471JOSknfW6QQKCUJztE7S/AeEFhrUVKghns+1YopL70N2L6jtz3BeparJV3X4ZxF5wbrenZNw7OTZ0ipsNay3qyJQZDrDKUU2/WWelQjBHR9x3q1RCmJVhLnPdE5tNKUVUGeFTRdS+8sJiuIQtK2PavNhqgULoJ1lvlyCVJhQ+A3fv/bnyj/fuSNzeHhIUopTk5O/pWPn5yccPv27T/w+Xmek+f5H/i4MQYhwPY9fZ9GlEVZMBpVeK9TwYdHa0PXdaz9hqPDA7SQSCF57bXXGE3GfPDhhzz8wQ+QSkBUaJ2zNzvi3/vSz9I0DWdnZ6is4O69+2RZxuV8ToyRXdPTdC2r1Yb1cgFELs7nvHb/Hpv1iqZpePvTb/Hd995Fycgrt2/xPHoQkqqq+epX/ySXiznOWaLWmKLAew9E6qrEXDVHSiFiSMWHNkCguXyOFIL9StM1ani4JFJpYtTDoceQkBkAQcBoVBFCoO9TISCVIkIqQLVCCoUUkt1uODCFToclsGs6rPeIaFjPV2y2G9q+Z3nZ0GwburajqKc8fnLK2fklL05OuFgskcZgzuc8+L/8Xymrkrqs2J/O+J//p/8pjz78kEcPP8A7ixIBYsB2js1iQds0uL4HYFKVTEY1WWaYzmZkZUFV5ZR1jjKaoiwZzol/41j6D5t//0M5OBpVjOqKg70Z07qgzHX6VeYYBRLHqMopjGF+Oefi9JQ3Xn/t+pAxRkFwSCHQSuJjpMoV2hhsUGityPIMk2W0vaPrOlSuqMsZSkVQ6TnQWg+HZ7rwlNEg0/ve9z1KSLRRFHlOVRXYPjUL9XiCtw7vHN57yjInBIP3Hu99Kt5iwFqbnrerOssMxezVay7zlMcxYIzBO4eU4rppkkIQQ6RtW7JM4X28/n6zXBJjRhgKXClTA7TdrhmVFd54ttstt/YPsday2Ww4P7/g4fsP6Ps
"text/plain": [
"<Figure size 1000x200 with 5 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
2022-11-27 19:15:49 +01:00
"source": [
"plt.figure(figsize=(10,2))\n",
"for i in range(5):\n",
" plt.subplot(151 + i)\n",
" plt.imshow(train_data[i][:,:,::-1]);"
]
},
{
"cell_type": "markdown",
"id": "e05e27e8",
"metadata": {},
"source": [
"Tworzymy deskryptor HOG przy pomocy funkcji [`cv.HOGDescriptor()`](https://docs.opencv.org/4.5.3/d5/d33/structcv_1_1HOGDescriptor.html). Metodą [`compute()`](https://docs.opencv.org/4.5.3/d5/d33/structcv_1_1HOGDescriptor.html#a38cd712cd5a6d9ed0344731fcd121e8b) tworzymy wektory cech, które posłużą nam jako dane wejściowe do klasyfikatora. Poniżej znajduje się również przykładowa konfiguracja deskryptora:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 7,
2022-11-27 19:15:49 +01:00
"id": "f21e8924",
"metadata": {},
"outputs": [],
"source": [
"hp_win_size = (96, 32)\n",
"hp_block_size = (8, 8)\n",
"hp_block_stride = (8, 8)\n",
"hp_cell_size = (4, 4)\n",
"hp_n_bins = 9\n",
"hp_deriv_aperture = 0\n",
"hp_win_sigma = 4.0\n",
"hp_histogram_norm_type = 1\n",
"hp_l2_hys_threshold = 0.2\n",
"hp_gamma_correction = True\n",
"hp_n_levels = 64\n",
"hp_signed_gradient = True\n",
"\n",
"hog_descriptor = cv.HOGDescriptor(\n",
" hp_win_size, hp_block_size, hp_block_stride, hp_cell_size, \n",
" hp_n_bins, hp_deriv_aperture, hp_win_sigma, \n",
" hp_histogram_norm_type, hp_l2_hys_threshold, \n",
" hp_gamma_correction, hp_n_levels, hp_signed_gradient)\n",
"\n",
"train_hog = np.vstack([hog_descriptor.compute(x).ravel() for x in train_data])\n",
"test_hog = np.vstack([hog_descriptor.compute(x).ravel() for x in test_data])"
]
},
{
"cell_type": "markdown",
"id": "755b8ebe",
"metadata": {},
"source": [
"Do klasyfikacji użyjemy klasyfikatora SVM. Możemy użyć implementacji znajdującej się w module [`cv.ml`](https://docs.opencv.org/4.5.3/d1/d2d/classcv_1_1ml_1_1SVM.html):"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 8,
2022-11-27 19:15:49 +01:00
"id": "b46783d4",
"metadata": {},
"outputs": [],
"source": [
"model = cv.ml.SVM_create()\n",
"model.setGamma(0.02)\n",
"model.setC(2.5)\n",
"model.setKernel(cv.ml.SVM_RBF)\n",
"model.setType(cv.ml.SVM_C_SVC)"
]
},
{
"cell_type": "markdown",
"id": "d8f47c54",
"metadata": {},
"source": [
"Trenujemy model:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 9,
2022-11-27 19:15:49 +01:00
"id": "810f9a1e",
"metadata": {},
"outputs": [],
"source": [
"model.train(np.array(train_hog), cv.ml.ROW_SAMPLE, train_labels);"
]
},
{
"cell_type": "markdown",
"id": "69d39eee",
"metadata": {},
"source": [
"Sprawdzamy wynik na danych testowych:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 10,
2022-11-27 19:15:49 +01:00
"id": "763b6dc7",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ACC: 92.48 %\n"
]
}
],
2022-11-27 19:15:49 +01:00
"source": [
"predictions = model.predict(test_hog)[1].ravel()\n",
"accuracy = (test_labels == predictions).mean()\n",
"print(f\"ACC: {accuracy * 100:.2f} %\")"
]
},
{
"cell_type": "markdown",
"id": "2dd04ec5",
"metadata": {},
"source": [
"Możemy również użyć implementacji klasyfikatora znajdującej się w bibliotece [`scikit-learn`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html):"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 11,
2022-11-27 19:15:49 +01:00
"id": "13b7ba1c",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ACC: 92.48 %\n"
]
}
],
2022-11-27 19:15:49 +01:00
"source": [
"model = sklearn.svm.SVC(C=2.5, gamma=0.02, kernel='rbf')\n",
"model.fit(train_hog, train_labels)\n",
"\n",
"predictions = model.predict(test_hog)\n",
"accuracy = (test_labels == predictions).mean()\n",
"print(f\"ACC: {accuracy * 100:.2f} %\")"
]
},
{
"cell_type": "markdown",
"id": "2259c310",
"metadata": {},
"source": [
"# Rozpoznawanie ludzi\n",
"\n",
"Powyższą metodykę klasyfikcji możemy zastosować do rozpoznawania obiektów na zdjęciach, np. ludzi. W tym wypadku będziemy chcieli wskazać gdzie na zdjęciu znajduje się dany obiekt lub obiekty.\n",
"\n",
"Rozpocznijmy od rozpakowania zbioru danych:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 12,
2022-11-27 19:15:49 +01:00
"id": "d8497390",
"metadata": {},
"outputs": [],
"source": [
"!cd datasets && unzip -qo inria-person-sub.zip"
]
},
{
"cell_type": "markdown",
"id": "30374bad",
"metadata": {},
"source": [
"Wczytujemy dane, które są już podzielone na dwa zbiory:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 13,
2022-11-27 19:15:49 +01:00
"id": "978d77cf",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train data: 1457, test data: 560\n"
]
}
],
2022-11-27 19:15:49 +01:00
"source": [
"dataset_dir = \"datasets/INRIAPerson\"\n",
"\n",
"images_train_0 = os.listdir(f\"{dataset_dir}/train_64x128_H96/negPatches\")\n",
"images_train_0 = [f\"{dataset_dir}/train_64x128_H96/negPatches/{x}\" for x in images_train_0]\n",
"images_train_1 = os.listdir(f\"{dataset_dir}/train_64x128_H96/posPatches\")\n",
"images_train_1 = [f\"{dataset_dir}/train_64x128_H96/posPatches/{x}\" for x in images_train_1]\n",
"\n",
"images_test_0 = os.listdir(f\"{dataset_dir}/test_64x128_H96/negPatches\")\n",
"images_test_0 = [f\"{dataset_dir}/test_64x128_H96/negPatches/{x}\" for x in images_test_0]\n",
"images_test_1 = os.listdir(f\"{dataset_dir}/test_64x128_H96/posPatches\")\n",
"images_test_1 = [f\"{dataset_dir}/test_64x128_H96/posPatches/{x}\" for x in images_test_1]\n",
"\n",
"train_data = []\n",
"test_data = []\n",
"train_labels = []\n",
"test_labels = []\n",
"\n",
"for x in images_train_0:\n",
" img = cv.imread(x, cv.IMREAD_COLOR)\n",
" if img is not None:\n",
" train_data.append(img)\n",
" train_labels.append(0)\n",
"\n",
"for x in images_train_1:\n",
" img = cv.imread(x, cv.IMREAD_COLOR)\n",
" if img is not None:\n",
" train_data.append(img)\n",
" train_labels.append(1)\n",
" \n",
"for x in images_test_0:\n",
" img = cv.imread(x, cv.IMREAD_COLOR)\n",
" if img is not None:\n",
" test_data.append(img)\n",
" test_labels.append(0)\n",
"\n",
"for x in images_test_1:\n",
" img = cv.imread(x, cv.IMREAD_COLOR)\n",
" if img is not None:\n",
" test_data.append(img)\n",
" test_labels.append(1)\n",
"\n",
"print(f\"Train data: {len(train_data)}, test data: {len(test_data)}\")"
]
},
{
"cell_type": "markdown",
"id": "9bf41d6e",
"metadata": {},
"source": [
"Poniżej znajduje się kilka przykładowych zdjęć ze zbioru:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 14,
2022-11-27 19:15:49 +01:00
"id": "f29d47c1",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1000x200 with 6 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
2022-11-27 19:15:49 +01:00
"source": [
"plt.figure(figsize=(10,2))\n",
"for i in range(3):\n",
" plt.subplot(161 + i)\n",
" plt.imshow(train_data[i][:,:,::-1]);\n",
"for i in range(3):\n",
" plt.subplot(164 + i)\n",
" plt.imshow(train_data[-(i+1)][:,:,::-1]);"
]
},
{
"cell_type": "markdown",
"id": "57cec468",
"metadata": {},
"source": [
"Tworzymy deskryptor i wektory cech:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 15,
2022-11-27 19:15:49 +01:00
"id": "d5248df2",
"metadata": {},
"outputs": [],
"source": [
"hp_win_size = (64, 128)\n",
"hp_block_size = (16, 16)\n",
"hp_block_stride = (8, 8)\n",
"hp_cell_size = (8, 8)\n",
"hp_n_bins = 9\n",
"hp_deriv_aperture = 1\n",
"hp_win_sigma = -1\n",
"hp_histogram_norm_type = 0\n",
"hp_l2_hys_threshold = 0.2\n",
"hp_gamma_correction = True\n",
"hp_n_levels = 64\n",
"hp_signed_gradient = False\n",
"\n",
"hog_descriptor = cv.HOGDescriptor(\n",
" hp_win_size, hp_block_size, hp_block_stride, hp_cell_size, \n",
" hp_n_bins, hp_deriv_aperture, hp_win_sigma, \n",
" hp_histogram_norm_type, hp_l2_hys_threshold, \n",
" hp_gamma_correction, hp_n_levels, hp_signed_gradient)\n",
"\n",
"train_hog = np.vstack([hog_descriptor.compute(x).ravel() for x in train_data])\n",
"test_hog = np.vstack([hog_descriptor.compute(x).ravel() for x in test_data])"
]
},
{
"cell_type": "markdown",
"id": "c6782aa9",
"metadata": {},
"source": [
"Następnie tworzymy klasyfikator:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 16,
2022-11-27 19:15:49 +01:00
"id": "8f6108ed",
"metadata": {},
"outputs": [],
"source": [
"model = cv.ml.SVM_create()\n",
"model.setGamma(0)\n",
"model.setC(0.01)\n",
"model.setKernel(cv.ml.SVM_LINEAR)\n",
"model.setType(cv.ml.SVM_C_SVC)\n",
"model.setTermCriteria((cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 1000, 1e-3))"
]
},
{
"cell_type": "markdown",
"id": "bbfbde58",
"metadata": {},
"source": [
"Uczymy model:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 17,
2022-11-27 19:15:49 +01:00
"id": "afd0bbb4",
"metadata": {},
"outputs": [],
"source": [
"model.train(np.array(train_hog), cv.ml.ROW_SAMPLE, np.array(train_labels));"
]
},
{
"cell_type": "markdown",
"id": "09626eed",
"metadata": {},
"source": [
"Sprawdzamy jakość klasyfikacji:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 18,
2022-11-27 19:15:49 +01:00
"id": "fa3be6b6",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ACC: 96.96 %\n"
]
}
],
2022-11-27 19:15:49 +01:00
"source": [
"predictions = model.predict(test_hog)[1].ravel()\n",
"accuracy = (test_labels == predictions).mean()\n",
"print(f\"ACC: {accuracy * 100:.2f} %\")"
]
},
{
"cell_type": "markdown",
"id": "c6df6682",
"metadata": {},
"source": [
"Poniżej znajduje się podejście przy pomocy biblioteki *scikit-learn*:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 19,
2022-11-27 19:15:49 +01:00
"id": "7b3de8d1",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Accuracy: 96.96 %\n",
"Precision: 93.55 %\n",
"Recall: 88.78 %\n"
]
}
],
2022-11-27 19:15:49 +01:00
"source": [
"model2 = sklearn.svm.SVC(C=0.01, gamma='auto', kernel='linear', max_iter=1000)\n",
"model2.fit(train_hog, train_labels)\n",
"\n",
"predictions = model2.predict(test_hog)\n",
"accuracy = (test_labels == predictions).mean()\n",
"print(f\"Accuracy: {sklearn.metrics.accuracy_score(test_labels, predictions) * 100:.2f} %\")\n",
"print(f\"Precision: {sklearn.metrics.precision_score(test_labels, predictions) * 100:.2f} %\")\n",
"print(f\"Recall: {sklearn.metrics.recall_score(test_labels, predictions) * 100:.2f} %\")"
]
},
{
"cell_type": "markdown",
"id": "6e84c568",
"metadata": {},
"source": [
"Mając teraz wyuczony model, chcielibyśmy sprawdzić czy np. na zdjęciu `img/pedestrians.jpg` znajdują się ludzie, tak aby uzyskać ew. obramowania z ich występowaniem. W pierwszej kolejności w naszym deskryptorze HOG ustawiamy współczynniki klasfikatora SVM przy pomocy metody [`setSVMDetector()`](https://docs.opencv.org/4.5.3/d5/d33/structcv_1_1HOGDescriptor.html#a6de5ac55631eed51e36278cde3a2c159). Następnie przy pomocy metody [`detectMultiScale()`](https://docs.opencv.org/4.5.3/d5/d33/structcv_1_1HOGDescriptor.html#a91e56a2c317392e50fbaa2f5dc78d30b) znajdujemy wyszukiwane obiekty (ludzi) w różnych skalach."
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 20,
2022-11-27 19:15:49 +01:00
"id": "d6458103",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 600x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
2022-11-27 19:15:49 +01:00
"source": [
"image = cv.imread(\"img/pedestrians.jpg\", cv.IMREAD_COLOR)\n",
"scale = 600 / image.shape[0]\n",
"image = cv.resize(image, None, fx=scale, fy=scale)\n",
"\n",
"support_vectors = model.getSupportVectors()\n",
"rho, _, _ = model.getDecisionFunction(0)\n",
"detector = np.zeros(support_vectors.shape[1] + 1, dtype=support_vectors.dtype)\n",
"detector[:-1] = -support_vectors[:]\n",
"detector[-1] = rho\n",
"\n",
"hog_descriptor.setSVMDetector(detector)\n",
"\n",
"locations, weights = hog_descriptor.detectMultiScale(\n",
" image, winStride=(8, 8), padding=(32, 32), scale=1.05,\n",
" finalThreshold=2, hitThreshold=1.0)\n",
"\n",
"for location, weight in zip(locations, weights):\n",
" x1, y1, w, h = location\n",
" x2, y2 = x1 + w, y1 + h\n",
" cv.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), thickness=3, lineType=cv.LINE_AA)\n",
" cv.putText(image, f\"{weight[0]:.2f}\", (x1,y1), cv.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2, cv.LINE_AA)\n",
"\n",
"plt.figure(figsize=(6,6))\n",
"plt.imshow(image[:,:,::-1]);"
]
},
{
"cell_type": "markdown",
"id": "cd287c92",
"metadata": {},
"source": [
"Coś nam nawet udało się wykryć jak na tak niewielki zbiór danych uczących ;) Z drugiej strony, dwie osoby na pierwszym planie zostały pominięte, a osoba po prawej jest dyskusyjna jeśli chodzi o zakres oznaczenia.\n",
"\n",
"W OpenCV dostępny jest domyślny klasyfikator w funkcji [`HOGDescriptor_getDefaultPeopleDetector()`](https://docs.opencv.org/4.5.3/d5/d33/structcv_1_1HOGDescriptor.html#a9c7a0b2aa72cf39b4b32b3eddea78203) i poniżej możemy zobaczyć jak sobie radzi na badanym zdjęciu:"
]
},
{
"cell_type": "code",
2023-01-09 09:56:02 +01:00
"execution_count": 21,
2022-11-27 19:15:49 +01:00
"id": "57a745c9",
"metadata": {},
2023-01-09 09:56:02 +01:00
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 600x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
2022-11-27 19:15:49 +01:00
"source": [
"image = cv.imread(\"img/pedestrians.jpg\", cv.IMREAD_COLOR)\n",
"scale = 600 / image.shape[0]\n",
"image = cv.resize(image, None, fx=scale, fy=scale)\n",
"\n",
"hog_dflt_descriptor = cv.HOGDescriptor(\n",
" hp_win_size, hp_block_size, hp_block_stride, hp_cell_size, \n",
" hp_n_bins, hp_deriv_aperture, hp_win_sigma, \n",
" hp_histogram_norm_type, hp_l2_hys_threshold, \n",
" hp_gamma_correction, hp_n_levels, hp_signed_gradient)\n",
"\n",
"detector_dflt = cv.HOGDescriptor_getDefaultPeopleDetector()\n",
"hog_dflt_descriptor.setSVMDetector(detector_dflt)\n",
"\n",
"locations, weights = hog_dflt_descriptor.detectMultiScale(\n",
" image, winStride=(8, 8), padding=(32, 32), scale=1.05,\n",
" finalThreshold=2, hitThreshold=1.0)\n",
"\n",
"for location, weight in zip(locations, weights):\n",
" x1, y1, w, h = location\n",
" x2, y2 = x1 + w, y1 + h\n",
" cv.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), thickness=3, lineType=cv.LINE_AA)\n",
" cv.putText(image, f\"{weight[0]:.2f}\", (x1,y1), cv.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2, cv.LINE_AA)\n",
"\n",
"plt.figure(figsize=(6,6))\n",
"plt.imshow(image[:,:,::-1]);"
]
},
{
"cell_type": "markdown",
"id": "6c8cf915",
"metadata": {},
"source": [
"# Segmentacja obrazu metodą GrabCut\n",
"\n",
"## Zadanie 1\n",
"\n",
"W poniższym zadaniu użyjemy algorytmu [GrabCut](https://en.wikipedia.org/wiki/GrabCut), będącego interaktywną metodą segmentacji obrazu, dzielącą obraz na pierwszy i drugi plan. W OpenCV algorytm jest zaimplementowany w funkcji [`cv.grabCut()`](https://docs.opencv.org/4.5.3/d3/d47/group__imgproc__segmentation.html#ga909c1dda50efcbeaa3ce126be862b37f). Dodatkowe informacje o algorytmie znajdują się w [dokumentacji](https://docs.opencv.org/4.5.3/d8/d83/tutorial_py_grabcut.html).\n",
"\n",
"Przygotuj interaktywną aplikację, która wykorzystuje algorytm GrabCut. W aplikacji powinna być możliwość zaznaczenia początkowego prostokąta, a następnie elementy maski (zwróć uwagę z jakich elementów może składać się maska). Przykładowe działanie możesz zaprezentować na obrazie `img/messi5.jpg`."
]
},
{
"cell_type": "markdown",
"id": "35f22bca",
"metadata": {},
"source": [
"![GrabCut - wynik](img/grabcut-result.png)"
]
2023-01-09 09:56:02 +01:00
},
{
"cell_type": "code",
"execution_count": 3,
"id": "7c740b51",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAigAAAFmCAYAAABHt2EEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAAD7DElEQVR4nOz9edztV13f/b/WWt9xz9c8nPlkTiAnZCBEoRoIQ6hYBm1R2lrxV+5W8VeL/ryLvdVy633zq3prxRGtFWyhVVRQqkYRJCCGEAIEMnLOyZmvedjzd1rD/cc+njZ1QCDJOQnr+Xhcydl7f/e+1tr7+3js9/Vda32WcM45PM/zPM/zLiHyYjfA8zzP8zzvf+UDiud5nud5lxwfUDzP8zzPu+T4gOJ5nud53iXHBxTP8zzP8y45PqB4nud5nnfJ8QHF8zzP87xLjg8onud5nuddcnxA8TzP8zzvkuMDiud5nud5l5yLGlB+4Rd+gYMHD5IkCbfeeiuf+tSnLmZzPM/zPM+7RFy0gPKbv/mbvOUtb+FHf/RH+cxnPsORI0d4+ctfzsbGxsVqkud5nud5lwhxsTYLvPXWW7nlllv4+Z//eQCstezbt4/v/d7v5d/8m39zMZrkeZ7ned4lIrgYv7QsS+6//37e+ta3XrhPSskdd9zBPffc81eOL4qCoigu3LbWsrOzw8zMDEKIp6XNnud5nud9dZxzDAYDlpeXkfJvH8S5KAFla2sLYwwLCwtPuH9hYYFHH330rxz/9re/nbe97W1PV/M8z/M8z3sKnTlzhr179/6txzwjVvG89a1vpdfrXfg5ffr0xW6S53me53lfoWaz+SWPuShXUGZnZ1FKsb6+/oT719fXWVxc/CvHx3FMHMdPV/M8z/M8z3sK/V2mZ1yUKyhRFHHTTTfx4Q9/+MJ91lo+/OEPc9ttt12MJnme53medwm5KFdQAN7ylrfwHd/xHdx88808//nP5z/8h//AaDTiO7/zOy9WkzzP8zzPu0RctIDyj/7RP2Jzc5Mf+ZEfYW1tjRtuuIG77rrrr0yc9TzP8zzva89Fq4Py1ej3+7Tb7YvdDM/zPM/zvgK9Xo9Wq/W3HvOMWMXjeZ7ned7XFh9QPM/zPM+75PiA4nme53neJccHFM/zPM/zLjk+oHie53med8nxAcXzPM/zvEuODyie53me511yfEDxPM/zPO+S4wOK53me53mXHB9QPM/zPM+75PiA4nme53neJccHFM/zPM/zLjk+oHie53med8nxAcXzPM/zvEuODyie53me511yfEDxPM/zPO+S4wOK53me53mXHB9QPM/zPM+75PiA4nme53neJccHFM/zPM/zLjk+oHie53med8nxAcXzPM/zvEuODyie53me511yfEDxPM/zPO+S4wOK53me53mXHB9QPM/zPM+75PiA4nme53neJccHFM/zPM/zLjk+oHie53med8nxAcXzPM/zvEuODyie53me511yfEDxPM/zPO+S4wOK53me53mXHB9QPM/zPM+75DzpAeXf/bt/hxDiCT9XX331hcfzPOd7vud7mJmZodFo8LrXvY719fUnuxme53me5z2DPSVXUK677jpWV1cv/Pz5n//5hcf+9b/+13zwgx/kfe97H3fffTcrKyu89rWvfSqa4Xme53neM1TwlLxoELC4uPhX7u/1evzar/0a733ve3nxi18MwK//+q9zzTXX8MlPfpIXvOAFT0VzPM/zPM97hnlKrqAcPXqU5eVlDh8+zBve8AZOnz4NwP33309VVdxxxx0Xjr366qvZv38/99xzz9/4ekVR0O/3n/DjeZ7ned6z15MeUG699Vbe9a53cdddd/FLv/RLnDhxghe96EUMBgPW1taIoohOp/OE5ywsLLC2tvY3vubb3/522u32hZ99+/Y92c32PM/zPO8S8qQP8dx5550X/n399ddz6623cuDAAX7rt36LNE2/otd861vfylve8pYLt/v9vg8pnud5nvcs9pQvM+50Olx55ZUcO3aMxcVFyrKk2+0+4Zj19fW/ds7KX4rjmFar9YQfz/M8z/OevZ7ygDIcDjl+/DhLS0vcdNNNhGHIhz/84QuPP/bYY5w+fZrbbrvtqW6K53me53nPEE/6EM8P/MAP8KpXvYoDBw6wsrLCj/7oj6KU4tu+7dtot9t813d9F295y1uYnp6m1Wrxvd/7vdx2221+BY/neZ7neRc86QHl7NmzfNu3fRvb29vMzc3xwhe+kE9+8pPMzc0B8DM/8zNIKXnd615HURS8/OUv5xd/8Ref7GZ4nud5nvcMJpxz7mI34svV7/dpt9sXuxme53me530Fer3el5xP6vfi8TzP8zzvkuMDiud5nud5lxwfUDzP8zzPu+T4gOJ5nud53iXHBxTP8zzP8y45PqB4nud5nnfJ8QHF8zzP87xLjg8onud5nuddcnxA8TzP8zzvkuMDiud5nud5lxwfUDzP8zzPu+T4gOJ5nud53iXHBxTP876kQEku3z9zsZvhed7XkOBiN8DzvEvL1NQ0YRhSb8bUGynD3R0CKYjD8GI3zfO8ryE+oHied0Gj3qDdbCGVot/fAQkqjHBGM8o09TSilsRs7g4udlM9z3uW8wHF8zwA4igkTUOybEhVaoJaRK8/oB6H5OMM6RSRktSbKSoM2djaBQcOhxQCB1jrLnY3PM97lvABxfM8AMIwRAjoD/sopcj6OUoFmKJEIRmOhsRJjApjpptNkjTAVRpnNPPzM2T5kIeObl7sbnie9yzhA4rneQBY57AIHJa8qEAoiqIijSLyqpg8ImAwHrO5u0OR5wRCkUQhmoBR5q+eeJ735PEBxfM8hBBIpbAIhAqw2uKMBQdlYcA5kI7KVOR9TaVLhBAYW2Gt49zqDnEcEkchVaUJAklZmYvdLc/znsF8QPE8D6kkQgryPMMYixAChwMk2hjAEkiB1RbrHNjzzxEOrS1FXiAlNBoJUgiKovABxfO8r4qvg+J53uQKihQYrbHGIBBIoXDO4bAIAdZajDY4axEOsA5nHM45yqqgqkqcc7RaTdK0drG75HneM5wPKJ7noaSilqQEUiEcOGOwbnLlBOFwOIwFYx3WAAicA4cAKXBS4ARIpXBCTO73PM/7KviA4nkezjmstUgpCYIApRRgUYFAyUkYEWJypWVyvMDaybJiIRRaa4ZZTl6WVMYQRr6om+d5Xx0/B8XzPJxzGDMZvsE5hJgEEyGZzERx4nw4EZNQAggpQUmQAiEVSIl2lt5gANqv6PE876vjr6B4nocxmvF4DEJgrcVaizYOY+z5qyQghMRaixAOhMM6DVZjrb0QcISShGGIVOpid8nzvGc4fwXF8zwAhJIgJkuNjZtMjI2iBCGgqswknCiJYrKCx7nJBFmYLEc2zpJEKXGcsr61hpTCV5b1PO8r5gPKM9B0q0Wr0UBrjTEG4ywbO7sXu1neM5SQgiiNEVJRlRXWOZQKCIKA6elppJT0ej2qqkIKh3AOnLkQPqw1qDAkDFOatTqNep2Z61psbe2wurJ+kXvned4zlQ8oz0Df8g0v5ptf/GJGoxFZWZDbit/4wz+azAnAYbQGBFJKnANtNPd9/vMXnt9ptbjy0CGklAghqLTmgYcfptL6ovXJu3jCJCFJaxhjkIEjVJPlxYGKSOIaUzPTLC0vo8sCayqG/S7ZqE9ZFJOrKFahwpg4SjBFyW6eU6ul6LK62F3zPO8ZzAeUZ6AHjj6GNoZvfvGL2bN3D/VWkxfcfAtBFAKOPMtBCKIoRamAcZHzk7/yTpwDnOPg3r285qUvI1CKIAgYlwW/+pv/jZOnz3D3ffde7O55T7NASYaDAWEYTIJJECCERAlJt7vL8vISe/ftYXd7k0Y9YWdjjfGwxnSnxWg4Js9yWlMzPHr8DPk4YzQeMRwOGAzzi901z/OewXxAeQYqrUMrSYnDCbDa4LRGVBpjNbqqiOI6ZVZhbEGSJrz1f/tuqrIkjmKMrnDWYitDVWrSKOL7vuONrG1ssLywwH/9779/sbvoPY2c1cShQgh3vkqsRqoACQjrMGXO8Ucfpd/f4Zorr+C
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"img = cv.imread(\"img/messi5.jpg\")\n",
"\n",
"top_left_corner=[]\n",
"bottom_right_corner=[]\n",
"rectangle_selected = True\n",
"mode = True\n",
"drawing = False\n",
"rect = (0,0,0,0)\n",
"mask = np.zeros(img.shape[:2],np.uint8)\n",
"mask += 2\n",
"bgdModel = np.zeros((1,65),np.float64)\n",
"fgdModel = np.zeros((1,65),np.float64)\n",
"\n",
"def drawRectangle(action, x, y, flags, *userdata):\n",
" global top_left_corner, bottom_right_corner, rectangle_selected, mode, drawing, rect\n",
"\n",
" if rectangle_selected is True:\n",
" if action == cv.EVENT_LBUTTONDOWN:\n",
" top_left_corner = [(x,y)]\n",
" elif action == cv.EVENT_LBUTTONUP:\n",
" bottom_right_corner = [(x,y)] \n",
" cv.rectangle(img, top_left_corner[0], bottom_right_corner[0], (255,0,0),2, 8)\n",
" for x in range(len(mask)):\n",
" for y in range(len(mask[0])):\n",
" if x < top_left_corner[0][1] or x > bottom_right_corner[0][1] or y < top_left_corner[0][0] or y > bottom_right_corner[0][0]:\n",
" mask[x][y] = 0\n",
" plt.imshow(mask)\n",
" rectangle_selected = False\n",
" else:\n",
" if action == cv.EVENT_LBUTTONDOWN:\n",
" drawing = True\n",
" elif action == cv.EVENT_MOUSEMOVE:\n",
" if drawing == True:\n",
" if mode == True:\n",
" cv.circle(img,(x,y),3,(0,255,0),-1)\n",
" else:\n",
" cv.circle(img,(x,y),3,(0,0,255),-1)\n",
" elif action == cv.EVENT_LBUTTONUP:\n",
" drawing = False\n",
"\n",
"\n",
"window_name = 'Messi';\n",
"cv.namedWindow(window_name)\n",
"cv.setMouseCallback(window_name, drawRectangle)\n",
"\n",
"img = cv.imread(\"img/messi5.jpg\")\n",
"while True:\n",
" cv.imshow(window_name, img)\n",
" code = cv.waitKey(1)\n",
"\n",
" if code == ord('q'):\n",
" break\n",
" if code == ord('m'):\n",
" mode = not mode\n",
" if code == ord('g'):\n",
" for x in range(len(img)):\n",
" for y in range(len(img[0])):\n",
" if (img[x][y] == (0, 0, 255)).all():\n",
" mask[x][y] = 0\n",
" if (img[x][y] == (0, 255, 0)).all():\n",
" mask[x][y] = 1\n",
"\n",
" img = cv.imread(\"img/messi5.jpg\")\n",
" cv.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv.GC_INIT_WITH_MASK)\n",
" mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')\n",
" img = img*mask2[:,:,np.newaxis]\n",
" plt.imshow(img[:,:,::-1])\n",
" break\n",
" \n",
"cv.destroyAllWindows()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "93addd33",
"metadata": {},
"outputs": [],
"source": []
2022-11-27 19:15:49 +01:00
}
],
"metadata": {
"author": "Andrzej Wójtowicz",
"email": "andre@amu.edu.pl",
"kernelspec": {
2023-01-09 09:56:02 +01:00
"display_name": "Python 3 (ipykernel)",
2022-11-27 19:15:49 +01:00
"language": "python",
"name": "python3"
},
"lang": "pl",
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
2023-01-09 09:56:02 +01:00
"version": "3.8.10"
2022-11-27 19:15:49 +01:00
},
"subtitle": "06. Segmentacja i rozpoznawanie obrazów [laboratoria]",
"title": "Widzenie komputerowe",
"year": "2021"
},
"nbformat": 4,
"nbformat_minor": 5
}