ეს ნოუთბუქი AI დამწყებთათვის სასწავლო პროგრამა-ის ნაწილია.
OpenCV ითვლება დე ფაქტო სტანდარტად გამოსახულების დამუშავებისთვის. ის შეიცავს უამრავ სასარგებლო ალგორითმს, რომელიც დანერგილია C++-ში. შეგიძლიათ დარეკოთ OpenCV პითონიდანაც.
ამ ნოუთბუქებში ჩვენ მოგცემთ OpenCV-ის გამოყენების მაგალითებს. დამატებითი ინფორმაციისთვის შეგიძლიათ ეწვიოთ ისწავლეთ OpenCV ონლაინ კურსს.
პირველ რიგში, მოდით import cv2, ისევე როგორც რამდენიმე სხვა სასარგებლო ბიბლიოთეკა:
იტვირთება…სურათების ჩატვირთვა
პითონში სურათები შეიძლება მოხერხებულად იყოს წარმოდგენილი NumPy მასივებით. მაგალითად, 320x200 პიქსელის ზომის ნაცრისფერი გამოსახულება შეინახება 200x320 მასივში, ხოლო იმავე განზომილების ფერადი გამოსახულება ექნება 200x320x3 (3 ფერადი არხისთვის).
დავიწყოთ სურათის ჩატვირთვით:
იტვირთება…გამოტანა
(242, 531, 3)
<matplotlib.image.AxesImage at 0x19a755cc640>
როგორც ხედავთ, ეს არის ბრაილის ტექსტის გამოსახულება. ვინაიდან ჩვენ ძალიან არ გვაინტერესებს რეალური ფერი, შეგვიძლია მისი გადაყვანა შავ-თეთრად:
იტვირთება…გამოტანა
(242, 531)
<matplotlib.image.AxesImage at 0x1de4dfef6a0>
ბრაილის სურათების დამუშავება
თუ გვინდა გამოვიყენოთ გამოსახულების კლასიფიკაცია ტექსტის ამოსაცნობად, ჩვენ უნდა ამოვაჭრათ ცალკეული სიმბოლოები, რათა ისინი გავხადოთ MNIST გამოსახულებების მსგავსი, რომლებიც ადრე ვნახეთ. ეს შეიძლება გაკეთდეს ობიექტის გამოვლენა ტექნიკის გამოყენებით, რომელსაც მოგვიანებით განვიხილავთ, მაგრამ ასევე შეგვიძლია ვცადოთ ამისთვის სუფთა კომპიუტერული ხედვის გამოყენება. კარგი აღწერა იმის შესახებ, თუ როგორ შეიძლება კომპიუტერული ხედვის გამოყენება პერსონაჟების განცალკევებისთვის, შეგიძლიათ იხილოთ ამ ბლოგის პოსტში - აქ მხოლოდ კომპიუტერული ხედვის ზოგიერთ ტექნიკაზე გავამახვილებთ ყურადღებას.
პირველ რიგში, შევეცადოთ ოდნავ გავაუმჯობესოთ გამოსახულება. ჩვენ შეგვიძლია გამოვიყენოთ ბარიერი (კარგად აღწერილი ამ OpenCV სტატიაში) იდეა:
იტვირთება…გამოტანა
<matplotlib.image.AxesImage at 0x1de4e26d9a0>
სურათებთან მუშაობისთვის საჭიროა ცალკეული წერტილების „ამოღება“, ანუ გადავიყვანოთ სურათები ცალკეული წერტილების კოორდინატებად. ჩვენ შეგვიძლია ამის გაკეთება ფუნქციების ამოღების ტექნიკის გამოყენებით, როგორიცაა SIFT, SURF ან ORB:
იტვირთება…გამოტანა
First 5 points: [(307.20001220703125, 40.80000305175781), (297.6000061035156, 114.00000762939453), (423.6000061035156, 133.20001220703125), (242.40000915527344, 144.0), (103.68000793457031, 57.60000228881836)]
მოდით დავხატოთ ყველა პუნქტი, რათა დავრწმუნდეთ, რომ ყველაფერი სწორად მივიღეთ:
იტვირთება…გამოტანა

ცალკეული სიმბოლოების გამოსაყოფად, ჩვენ უნდა ვიცოდეთ მთელი ტექსტის შეზღუდვის ველი. ამის გასარკვევად, ჩვენ შეგვიძლია უბრალოდ გამოვთვალოთ min და max კოორდინატები:
იტვირთება…გამოტანა
<matplotlib.image.AxesImage at 0x1de74b0fac0>
ასევე, ამ ტექსტის ნაწილობრივი როტაცია შესაძლებელია და მისი სრულყოფილად გასწორების მიზნით ჩვენ უნდა გავაკეთოთ ეგრეთ წოდებული პერსპექტიული ტრანსფორმაცია. ჩვენ ავიღებთ $(x_{min},y_{min}), (x_{min},y_{max}), (x_{max},y_{min}), (x_{max},y_{max})$ წერტილებით განსაზღვრულ ოთხკუთხედს და გავასწორებთ ახალ სურათს პროპორციული ზომებით:
იტვირთება…გამოტანა
<matplotlib.image.AxesImage at 0x1de74cf0f70>
მას შემდეგ რაც მივიღებთ ამ კარგად გასწორებულ სურათს, შედარებით ადვილი უნდა იყოს მისი ნაწილებად დაჭრა:
იტვირთება…გამოტანა

თქვენ ნახეთ, რომ საკმაოდ ბევრი დავალების შესრულება შესაძლებელია სუფთა გამოსახულების დამუშავების გამოყენებით, ყოველგვარი AIს გარეშე. თუ ჩვენ შეგვიძლია გამოვიყენოთ კომპიუტერული ხედვის ტექნიკა, რათა გავამარტივოთ ნერვული ქსელის მუშაობა - ეს აუცილებლად უნდა გავაკეთოთ, რადგან ეს მოგვცემს საშუალებას მოვაგვაროთ პრობლემები მცირე რაოდენობის სასწავლო მონაცემებით.
მოძრაობის გამოვლენა ჩარჩოს განსხვავების გამოყენებით
ვიდეო ნაკადზე მოძრაობის გამოვლენა ძალიან ხშირი ამოცანაა. მაგალითად, ის საშუალებას გვაძლევს მივიღოთ გაფრთხილებები, როდესაც რაღაც ხდება სათვალთვალო კამერაზე. If we want to understand what's happening on the camera, we can then use a neural network - but it is much cheaper to use neural network when we know that something is going on.
The main idea of motion detection is simple. თუ კამერა ფიქსირდება, მაშინ კამერის ჩარჩოები საკმაოდ მსგავსი უნდა იყოს ერთმანეთის. ვინაიდან ჩარჩოები წარმოდგენილია როგორც მასივები, მხოლოდ ამ მასივების გამოკლებით ორ მომდევნო კადრს მივიღებთ პიქსელების განსხვავებას, რომელიც დაბალი უნდა იყოს სტატიკური ჩარჩოებისთვის და უფრო მაღალი გახდება, როდესაც სურათზე მნიშვნელოვანი მოძრაობა იქნება.
ჩვენ დავიწყებთ იმით, რომ ვისწავლოთ ვიდეოს გახსნა და მისი გადაქცევა კადრების თანმიმდევრობით:
იტვირთება…გამოტანა
Total frames: 876
<Figure size 2592x1728 with 6 Axes>Since color is not so important for motion detection, we will convert all frames to grayscale. Then, we will compute the frame differences, and plot their norms to visually see the amount of activity going on:
იტვირთება…გამოტანა


დავუშვათ, რომ გვინდა შევქმნათ მოხსენება, რომელიც აჩვენებს, თუ რა მოხდა კამერის წინ, შესაბამისი სურათის ჩვენებით ყოველ ჯერზე, როცა რაღაც მოხდება. ამისათვის ჩვენ ალბათ გვინდა გავარკვიოთ "მოვლენის" საწყისი და დასასრული ჩარჩო და გამოვაჩინოთ შუა ჩარჩო. გარკვეული ხმაურის მოსაშორებლად, ჩვენ ასევე გავასწორებთ ზემოთ მოცემულ მრუდს მოძრავი საშუალო ფუნქციით:
იტვირთება…გამოტანა
<matplotlib.lines.Line2D at 0x1de72d816d0>
ახლა ჩვენ შეგვიძლია გავარკვიოთ ჩარჩოები, რომლებსაც აქვთ ცვლილებების რაოდენობა ზღურბლზე ზემოთ np.where-ის გამოყენებით და გამოვყოთ თანმიმდევრული კადრების თანმიმდევრობა, რომელიც 30 ფრეიმზე მეტია:
იტვირთება…გამოტანა
[195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322]
და ბოლოს ჩვენ შეგვიძლია გამოვხატოთ სურათი:
იტვირთება…გამოტანა
<matplotlib.image.AxesImage at 0x1de74da5b80>
თქვენ შეიძლება შეამჩნიოთ, რომ ამ სურათზე ფერადი სქემა არ გამოიყურება სწორად! ეს იმიტომ ხდება, რომ OpenCV ისტორიული მიზეზების გამო ატვირთავს სურათებს BGR ფერთა სივრცეში, ხოლო matplotlib იყენებს უფრო ტრადიციულ RGB ფერის წესრიგს. უმეტეს შემთხვევაში, აზრი აქვს სურათების RGB-ში გადაყვანას მათი ჩატვირთვისთანავე.
იტვირთება…გამოტანა
<matplotlib.image.AxesImage at 0x1dec94969d0>
ამოიღეთ მოძრაობა ოპტიკური ნაკადის გამოყენებით
მიუხედავად იმისა, რომ მხოლოდ ორი თანმიმდევრული ჩარჩოს შედარება საშუალებას გვაძლევს დავინახოთ ცვლილებების რაოდენობა, ის არ გვაძლევს ინფორმაციას იმის შესახებ, თუ რა მოძრაობს რეალურად და სად. ამ ინფორმაციის მისაღებად, არსებობს ტექნიკა, სახელწოდებით ოპტიკური ნაკადი:
- მკვრივი ოპტიკური ნაკადი ითვლის ვექტორულ ველს, რომელიც აჩვენებს თითოეულ პიქსელს სად მოძრაობს იგი
- მწირი ოპტიკური ნაკადი ეფუძნება გამოსახულების ზოგიერთი გამორჩეული მახასიათებლის აღებას (მაგ. კიდეები) და მათი ტრაექტორიის აგებას ჩარჩოდან ჩარჩოში.
წაიკითხეთ მეტი ოპტიკური ნაკადის შესახებ ამ დიდ ტუტორიალში.
მოდით გამოვთვალოთ მკვრივი ოპტიკური ნაკადი ჩვენს ჩარჩოებს შორის:
იტვირთება…გამოტანა
(180, 320, 2)როგორც ხედავთ, თითოეული ჩარჩოსთვის ნაკადს აქვს ჩარჩოს განზომილება და 2 არხი, რომელიც შეესაბამება ოპტიკური ნაკადის ვექტორის x და y კომპონენტებს.
2D ოპტიკური ნაკადის ჩვენება ცოტა რთულია, მაგრამ ჩვენ შეგვიძლია გამოვიყენოთ ერთი ჭკვიანი იდეა. თუ ოპტიკურ ნაკადს გადავიყვანთ პოლარულ კოორდინატებად, მაშინ მივიღებთ ორ კომპონენტს თითოეული პიქსელისთვის: მიმართულება და ინტენსივობა. ჩვენ შეგვიძლია წარმოვადგინოთ ინტენსივობა პიქსელის ინტენსივობით, ხოლო მიმართულება სხვადასხვა ფერებით. ჩვენ შევქმნით სურათს HSV (Hue-Saturation-Value) ფერის სივრცე-ში, სადაც ელფერი განისაზღვრება მიმართულებით, მნიშვნელობა - ინტენსივობით და გაჯერება იქნება 255.
იტვირთება…გამოტანა
195 322

ასე რომ, ამ ჩარჩოებში მომწვანო ფერი შეესაბამება მარცხნივ მოძრაობას, ხოლო ლურჯი - მარჯვნივ მოძრაობას.
ოპტიკური ნაკადი შეიძლება იყოს შესანიშნავი ინსტრუმენტი მოძრაობის ზოგადი მიმართულების შესახებ დასკვნების გამოსატანად. მაგალითად, თუ ხედავთ, რომ ჩარჩოში ყველა პიქსელი მოძრაობს მეტ-ნაკლებად ერთი მიმართულებით - შეგიძლიათ დაასკვნათ, რომ არის კამერის მოძრაობა და შეეცადეთ ამის კომპენსირება.