Advertisement
Guest User

Untitled

a guest
Mar 21st, 2019
37
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.06 KB | None | 0 0
  1. # Основы opencv (на с++)
  2. ## Вместо вступления
  3. Это рукодоство должно дать базовые знания об opencv, с помощью которых можно искать решения практических задач в интернете (или посмотреть в этой репе). Не рекомендуется смотреть полные руководства в интернете, т.к. большинство из них используют старую версию opencv с другими типами переменных, которые несовместимы с новыми функциями. Полная документация к opencv доступна [тут](https://docs.opencv.org/).
  4. ## Что такое opencv?
  5. Opencv (OPEN source Computer Vision library) - библиотека для компьютерного зрения (оно же видеозрение и техническое зрение), т.е. для обнаружения и классификации объектов на изображении. Реализована на c++, java, python, ruby, matlab и lua.
  6. ## Opencv на python
  7. `opencv-python` - название opencv в pip
  8.  
  9. `cv2` - название модуля opencv
  10.  
  11. Изображение - массив numpy в формате BGR, т.е. RGB наоборот.
  12.  
  13. `cv2.VideoCapture` - класс, читающий кадры с камеры или из видео
  14.  
  15. `cap = cv2.VideoCapture(0)` - откроет камеру #0. `cap = cv2.VideoCapture('videos/vid.mp4')` - откроет видео
  16.  
  17. `_, frame = cap.read()` - прочитает кадр из `cap`.
  18. `cv2.imshow("hello world", frame)` - покажет frame в окне с именем hello world.
  19.  
  20. Дальше сами разберетесь, не маленькие уже. В дальнейшем речь идет об opencv на c++
  21. ## Hello world
  22. Напишем самую простую программу - которая выводит на экран видеопоток с камеры
  23.  
  24. Для начала, подключим заголовки opencv и прочую шнягу (предполагается, что opencv уже скомпилировано, если ты под линуксом или проект сконфигурирован, если ты под виндой)
  25. Если opencv еще не скомпилировано, то читаем это руководство: [Компиляция opencv для Linux](Компиляция opencv для Linux)
  26.  
  27. ```c++
  28. #include "opencv2/opencv.hpp"
  29.  
  30. using namespace cv;
  31. ```
  32.  
  33. Все функции и классы в opencv завернуты в namespace cv
  34.  
  35. Видеопоток в opencv имеет тип `VideoCapture`. Это класс, который способен открывать видео и выдавать изображение по кадрам. Открытие видео с камеры осуществляется через метод `.open(int device)`, где `device` - номер камеры, с которой снимается видео. Его проще всего находить подбором, обычно это 0.
  36.  
  37. Итак, создание объекта типа `VideoCapture` и открытие видео выглядят вот так (это, очевидно, в `main`):
  38. ```c++
  39. VideoCapture cap;
  40. cap.open(0);
  41. ```
  42. Также можно открывать видео, прописав в `.open()` вместо номера камеры путь к файлу видео, например `cap.open("videos/vid.mp4");`
  43.  
  44. Теперь мы хотим получить изображение из видеопотока. Это делается при помощи оператора `>>`, и изображение записывается в объект класса `Mat` - матрица, класс для изображений в opencv. Так как мы хотим получить не одно изображение, а считывать их с камеры постоянно, то мы будем это делать в бесконечном цикле. Также необходимо объявить матрицу.
  45.  
  46. ```c++
  47. Mat img;
  48.  
  49. while(true)
  50. {
  51. cap >> img;
  52. }
  53. ```
  54.  
  55. Мы получаем изображение из видеопотока, теперь нужно его вывести на экран. Для этого есть функция `imshow(std::string winname, Mat input)`. Она выводит изображение `input` в окно с названием `winname`. Также нужно вызвать фунцкию `waitKey(int msec)`, которая ждет нажатия кнопки на клавиатуре пользователя, чтобы окно отрисовалось.
  56.  
  57. ```c++
  58. imshow("Hello world!", img);
  59. waitKey(1);
  60. ```
  61.  
  62. Если ты все переписал правильно и в нужном порядке, то у тебя появилось окно, в котором видно изображение с камеры. Если нет, то попроси кого-нибудь, кто свободен и разбирается в opencv, тебе помочь.
  63.  
  64. Ты поверхностно познакомился с `VideoCapture` и `Mat`. Теперь посмотрим на них чуть более детально.
  65.  
  66. ## VideoCapture
  67.  
  68. У `VideoCapture` есть полезный метод - `isOpened()`. Его можно использовать, чтобы проверять, что видеопоток открылся нормально, например:
  69. ```c++
  70. if (!cap.isOpened())
  71. {
  72. std::cout << "Could not open the capture" << std::endl;
  73. return -1;
  74. }
  75. ```
  76.  
  77. Также можно использовать ip-камеры, которые передают видео через wi-fi, например `cap.open("http:\\10.0.1.2\video.mpeg");`
  78.  
  79. ## Mat
  80.  
  81. Изображения можно читать из файла с помощью функции `imread(std::string filename)`, например `Mat img = imread("imgs/saple.img");`
  82.  
  83. `.data` возвращает указатель на сырые данные изображения. Хотя он редко используется, он полезен для проверки, есть ли в изображении какие-либо данные, например:
  84. ```c++
  85. if(!img.data)
  86. {
  87. std::cout << "The image is empty" << std::endl;
  88. return -1;
  89. }
  90. ```
  91.  
  92. Изображения в opencv хранятся в формате BGR, то есть RGB наоборот. В другие форматы можно переводить при помощи `cvtColor(Mat input, Mat output, int code)`, например `cvtColor(img, imgHSV, CV_BGR2HSV)`. Такой перевод может понадобиться, например, для выделения объекта по его цвету (colorfind.cpp)
  93.  
  94. Размер матрицы можно получить с помощью `.size()`, который возвращает объект типа `Size`, о котором будет сказано в следующей части. Также её размер можно получить при помощи `.cols` и `.rows`, которые возвращают число рядов и столбцов соответственно.
  95.  
  96. К пикселям из `Mat` можно обращаться через `.at()`, как в этом цикле по всем пикслеям (он не протестирован, возможно нужно поменять местами `cols` и `rows`):
  97. ```c++
  98. for (int x = 0; x < img.cols; x++)
  99. {
  100. for (int y = 0; y < img.rows; y++)
  101. {
  102. Scalar color = img.at<Vec3b>(y, x);
  103. //что-то делаем с color
  104. }
  105. }
  106. ```
  107. Тут ты столкнулся с двумя новым типами - `Scalar` и `Vec3b`, что ведет нас к следующей части.
  108.  
  109. ## Прочие классы в opencv
  110.  
  111. `Scalar` - класс, содержащий в себе 4 элемента любого типа, доступ к которым осуществляется через `[]`. `Vec` - множество классов, состоящих из `n` элементов, где `n` - число, стоящее после `Vec`. Тип у этих элементов задается буквой, стоящей после `n`.
  112.  
  113. | Буква | Тип |
  114. |:-----:|:------:|
  115. | b | byte |
  116. | i | int |
  117. | s | short |
  118. | f | float |
  119. | d | double |
  120.  
  121. Например, `Vec3b` - класс из трёх элементов типа byte.
  122.  
  123. Как несложно догадаться, `Scalar` - дочерний класс `Vec`. Зачем он сделан - непонятно.
  124.  
  125. `Point` - класс, также часто использующийся в opencv. Обозначает он - ты не поверишь - точку. Он похож на `Vec` тем, что задается аналогично - число, стоящее после `Point`, обозначает число элементов в нем, а буква после этого обозначает тип данных. Но обращение к данным осуществляется через `.x`, `.y` и `.z`. Также на `Point` заданы операции сложения, вычитания и деления.
  126.  
  127. `Size` - класс для обозначения размеров изображения или прямоугольника. `.width` и `.height` - ширина и высота соответственно.
  128.  
  129. ## Заключение
  130.  
  131. Все дальнейшее можно узнать, почитав документацию по opencv вот [тут](docs.opencv.org). Если что непонятно и не гуглится, всегда можно спросить кого-нибудь из лабы. И не забывайте заглядывать в usefulcode, возможно ваша задача там уже решена.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement