OpenCV Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π΄ΠΈΠ·Π°ΡΠ½ΠΈΡΠ°Π½Π° Π·Π° ΠΏΡΠΎΠ΅ΠΊΡΠΈ Π·Π° ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΡΠΊΠ° Π²ΠΈΠ·ΠΈΡΠ°. Π’Π°Π° Π²Π΅ΡΠ΅ ΠΈΠΌΠ° ΠΎΠΊΠΎΠ»Ρ 20 Π³ΠΎΠ΄ΠΈΠ½ΠΈ. ΠΠΎ ΠΊΠΎΡΠΈΡΡΠ΅Π² Π½Π° ΡΠ°ΠΊΡΠ»ΡΠ΅Ρ ΠΈ ΡΓ¨ ΡΡΡΠ΅ Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠ°ΠΌ Π·Π° ΠΌΠΎΠΈΡΠ΅ C++ ΠΈ Python ΠΏΡΠΎΠ΅ΠΊΡΠΈ Π±ΠΈΠ΄Π΅ΡΡΠΈ ΠΈΠΌΠ° Π΄ΠΎΠ±ΡΠ° ΠΏΠΎΠ΄Π΄ΡΡΠΊΠ° Π·Π° ΡΠΈΠ΅ ΡΠ°Π·ΠΈΡΠΈ.
ΠΠΎ, ΠΊΠΎΠ³Π° ΠΏΠΎΡΠ½Π°Π² Π΄Π° ΡΡΠ°ΠΌ ΠΈ Π΄Π° Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠ°ΠΌ Go, ΡΠ΅ Π·Π°ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠΈΡΠ°Π² Π΄Π°Π»ΠΈ OpenCV ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ ΠΎΠ²ΠΎΡ ΡΠ°Π·ΠΈΠΊ. ΠΠΎ ΡΠΎΠ° Π²ΡΠ΅ΠΌΠ΅ Π²Π΅ΡΠ΅ ΠΈΠΌΠ°ΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈ ΠΈ ΡΡΡΠΎΡΠΈΡΠ°Π»ΠΈ Π·Π° ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡΠ°, Π½ΠΎ ΠΌΠΈ ΡΠ΅ ΡΠΈΠ½Π΅ΡΠ΅ Π΄Π΅ΠΊΠ° ΡΠ΅ ΠΏΡΠ΅ΠΌΠ½ΠΎΠ³Ρ ΠΊΠΎΠΌΠΏΠ»ΠΈΡΠΈΡΠ°Π½ΠΈ. ΠΠ°Π»ΠΊΡ ΠΏΠΎΠ΄ΠΎΡΠ½Π°, Π½Π°ΠΈΠ΄ΠΎΠ² Π½Π° ΠΎΠ±Π²ΠΈΠ²ΠΊΠ° ΡΠΎΠ·Π΄Π°Π΄Π΅Π½Π° ΠΎΠ΄ ΡΠΈΠΌΠΎΡ Π½Π° The Hybrid Group. ΠΠΎ ΠΎΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ°, ΡΠ΅ Π²ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ°ΠΌ ΠΊΠ°ΠΊΠΎ Π΄Π° Π·Π°ΠΏΠΎΡΠ½Π΅ΡΠ΅ ΡΠΎ GoCV ΡΠΎ ΡΠ°Π·Π²ΠΈΠ²Π°ΡΠ΅ Π½Π° Π΅Π΄Π½ΠΎΡΡΠ°Π²Π΅Π½ ΡΠΈΡΡΠ΅ΠΌ Π·Π° ΠΏΡΠ΅ΠΏΠΎΠ·Π½Π°Π²Π°ΡΠ΅ Π»ΠΈΡΠ΅ ΡΠΎ Haar Cascades.
Skillbox ΠΏΡΠ΅ΠΏΠΎΡΠ°ΡΡΠ²Π°: ΠΡΠ°ΠΊΡΠΈΡΠ΅Π½ ΠΊΡΡΡ
βΠΡΠΎΠ³ΡΠ°ΠΌΠ΅Ρ Π½Π° Python ΠΎΠ΄ Π½ΡΠ»Π°β .ΠΠΎΡΡΠ΅ΡΡΠ²Π°ΠΌΠ΅: Π·Π° ΡΠΈΡΠ΅ ΡΠΈΡΠ°ΡΠ΅Π»ΠΈ Π½Π° βΠ₯Π°Π±Ρβ - ΠΏΠΎΠΏΡΡΡ ΠΎΠ΄ 10 ΡΡΠ±Π»ΠΈ ΠΏΡΠΈ Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΊΠΎΡ Π±ΠΈΠ»ΠΎ ΠΊΡΡΡ Skillbox ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ Π³ΠΎ ΠΏΡΠΎΠΌΠΎΡΠΈΠ²Π½ΠΈΠΎΡ ΠΊΠΎΠ΄ βΠ₯Π°Π±Ρβ.
Π¨ΡΠΎ Π΅ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎ:
- ΠΠ΄ΠΈ;
- OpenCV (Π²ΡΡΠΊΠΈ Π·Π° ΠΈΠ½ΡΡΠ°Π»Π°ΡΠ΅Ρ ΠΏΠΎΠ΄ΠΎΠ»Ρ);
- Π²Π΅Π± ΠΈΠ»ΠΈ ΠΎΠ±ΠΈΡΠ½Π° Π²ΠΈΠ΄Π΅ΠΎ ΠΊΠ°ΠΌΠ΅ΡΠ°.
ΠΠ½ΡΡΠ°Π»Π°ΡΠΈΡΠ°
- Linux:
gocv.io/getting-started/linux - MacOS:
gocv.io/getting-started/macos - ΠΡΠΎΠ·ΠΎΡΡΠΈ:
gocv.io/getting-started/windows
ΠΏΡΠΈΠΌΠ΅Ρ 1
ΠΠΎ ΠΏΡΠ²ΠΈΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ΅ ΡΠ΅ ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° ΡΠΎΠ·Π΄Π°Π΄Π΅ΠΌΠ΅ Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ° ΠΊΠΎΡΠ° ΠΎΡΠ²ΠΎΡΠ° ΠΏΡΠΎΠ·ΠΎΡΠ΅Ρ ΡΡΠΎ ΠΏΡΠΈΠΊΠ°ΠΆΡΠ²Π° Π²ΠΈΠ΄Π΅ΠΎ-ΡΡΡΠΈΠΌ ΠΎΠ΄ ΠΊΠ°ΠΌΠ΅ΡΠ°ΡΠ°.
ΠΡΠ²ΠΎ ΡΡΠ΅Π±Π° Π΄Π° Π³ΠΈ ΡΠ²Π΅Π·Π΅ΡΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈΡΠ΅ ΠΏΠΎΡΡΠ΅Π±Π½ΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ°.
ΡΠ²ΠΎΠ· (
"Π΄Π½Π΅Π²Π½ΠΈΠΊ"
βgocv.io/x/gocvβ
)
ΠΠΎ ΠΎΠ²Π°, ΡΡΠ΅Π±Π° Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡ VideoCapture ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° VideoCaptureDevice. ΠΡΠΎΡΠΈΠΎΡ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° ΡΠ½ΠΈΠΌΠ°ΡΠ΅ Π½Π° Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΡΠΎΠΊ ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΠΊΠ°ΠΌΠ΅ΡΠ°. Π€ΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° ΠΊΠΎΡΠΈΡΡΠΈ ΡΠ΅Π» Π±ΡΠΎΡ ΠΊΠ°ΠΊΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΠ°Ρ (Π³ΠΎ ΠΏΡΠ΅ΡΡΡΠ°Π²ΡΠ²Π° ID Π½Π° ΡΡΠ΅Π΄ΠΎΡ).
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil { log.Fatalf(βerror opening web cam: %vβ, err)
}
defer webcam.Close()
Π‘Π΅Π³Π° ΡΡΠ΅Π±Π° Π΄Π° ΡΠΎΠ·Π΄Π°Π΄Π΅ΠΌΠ΅ n-Π΄ΠΈΠΌΠ΅Π½Π·ΠΈΠΎΠ½Π°Π»Π½Π° ΠΌΠ°ΡΡΠΈΡΠ°. ΠΠ΅ Π³ΠΈ ΡΠΊΠ»Π°Π΄ΠΈΡΠ° ΡΠ»ΠΈΠΊΠΈΡΠ΅ ΠΏΡΠΎΡΠΈΡΠ°Π½ΠΈ ΠΎΠ΄ ΠΊΠ°ΠΌΠ΅ΡΠ°ΡΠ°.
img := gocv.NewMat()
defer img.Close()
ΠΠ° Π΄Π° ΠΏΡΠΈΠΊΠ°ΠΆΠ΅ΡΠ΅ Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΡΠΎΠΊ, ΡΡΠ΅Π±Π° Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΏΡΠΎΠ·ΠΎΡΠ΅Ρ - ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΠΏΡΠ°Π²ΠΈ ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° NewWindow.
window := gocv.NewWindow(βwebcamwindowβ)
defer window.Close()
Π‘Π΅Π³Π° Π΄Π° ΠΏΡΠ΅ΠΌΠΈΠ½Π΅ΠΌΠ΅ Π½Π° Π½Π°ΡΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΈΠΎΡ Π΄Π΅Π».
ΠΠΈΠ΄Π΅ΡΡΠΈ Π²ΠΈΠ΄Π΅ΠΎΡΠΎ Π΅ ΠΊΠΎΠ½ΡΠΈΠ½ΡΠΈΡΠ°Π½ ΠΏΡΠΈΠ»ΠΈΠ² Π½Π° ΡΠ°ΠΌΠΊΠΈ Π·Π° ΡΠ»ΠΈΠΊΠΈ, ΡΠ΅ ΡΡΠ΅Π±Π° Π΄Π° ΡΠΎΠ·Π΄Π°Π΄Π΅ΠΌΠ΅ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½Π° ΡΠ°ΠΌΠΊΠ° Π·Π° Π±Π΅ΡΠΊΡΠ°ΡΠ½ΠΎ Π΄Π° Π³ΠΎ ΡΠΈΡΠ°ΠΌΠ΅ Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΡΠΎΠΊΠΎΡ Π½Π° ΠΊΠ°ΠΌΠ΅ΡΠ°ΡΠ°. ΠΠ° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΠ²Π°, ΠΏΠΎΡΡΠ΅Π±Π΅Π½ Π²ΠΈ Π΅ ΠΌΠ΅ΡΠΎΠ΄ΠΎΡ Read ΠΎΠ΄ ΡΠΈΠΏΠΎΡ VideoCapture. ΠΠ΅ ΠΎΡΠ΅ΠΊΡΠ²Π° ΡΠΈΠΏ Mat (ΠΌΠ°ΡΡΠΈΡΠ°ΡΠ° ΡΡΠΎ ΡΠ° ΡΠΎΠ·Π΄Π°Π΄ΠΎΠ²ΠΌΠ΅ ΠΏΠΎΠ³ΠΎΡΠ΅), Π²ΡΠ°ΡΠ°ΡΡΠΈ Π±ΡΠ»ΠΎΠ²Π° Π²ΡΠ΅Π΄Π½ΠΎΡΡ ΡΡΠΎ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π° Π΄Π°Π»ΠΈ ΡΠ°ΠΌΠΊΠ°ΡΠ° ΠΎΠ΄ VideoCapture Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΏΡΠΎΡΠΈΡΠ°Π½Π° ΠΈΠ»ΠΈ Π½Π΅.
for {
if ok := webcam.Read(&img); !ok || img.Empty( {
log.Println(βUnable to read from the webcamβ) continue
}
.
.
.
}
Π‘Π΅Π³Π° ΡΡΠ΅Π±Π° Π΄Π° ΡΠ° ΠΏΡΠΈΠΊΠ°ΠΆΠ΅ΡΠ΅ ΡΠ°ΠΌΠΊΠ°ΡΠ° Π²ΠΎ ΠΊΡΠ΅ΠΈΡΠ°Π½ΠΈΠΎΡ ΠΏΡΠΎΠ·ΠΎΡΠ΅Ρ. ΠΠ°ΡΠ·Π°ΡΠ° Π·Π° ΠΏΡΠ΅ΠΌΠΈΠ½ΡΠ²Π°ΡΠ΅ Π½Π° ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΠ°ΠΌΠΊΠ° Π΅ 50 ms.
ΠΏΡΠΎΠ·ΠΎΡΠ΅Ρ.IMShow(img)
ΠΏΡΠΎΠ·ΠΎΡΠ΅Ρ.WaitKey(50)
ΠΡΠΊΠ°ΠΊΠΎ ΡΠ΅ ΡΠ° ΡΡΠ°ΡΡΡΠ²Π°ΡΠ΅ Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ°ΡΠ°, ΡΠ΅ ΡΠ΅ ΠΎΡΠ²ΠΎΡΠΈ ΠΏΡΠΎΠ·ΠΎΡΠ΅Ρ ΡΠΎ Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΡΠΎΠΊ ΠΎΠ΄ ΠΊΠ°ΠΌΠ΅ΡΠ°ΡΠ°.
package main
import (
"log"
"gocv.io/x/gocv"
)
func main() {
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil {
log.Fatalf("error opening device: %v", err)
}
defer webcam.Close()
img := gocv.NewMat()
defer img.Close()
window := gocv.NewWindow("webcamwindow")
defer window.Close()
for {
if ok := webcam.Read(&img); !ok || img.Empty() {
log.Println("Unable to read from the webcam")
continue
}
window.IMShow(img)
window.WaitKey(50)
}
}
ΠΏΡΠΈΠΌΠ΅Ρ 2
ΠΠΎ ΠΎΠ²ΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π° Π³ΠΎ ΠΈΡΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ ΠΏΡΠ΅ΡΡ ΠΎΠ΄Π½ΠΈΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ ΠΈ Π΄Π° ΠΈΠ·Π³ΡΠ°Π΄ΠΈΠΌΠ΅ ΡΠΈΡΡΠ΅ΠΌ Π·Π° ΠΏΡΠ΅ΠΏΠΎΠ·Π½Π°Π²Π°ΡΠ΅ Π»ΠΈΡΠ° Π±Π°Π·ΠΈΡΠ°Π½ Π½Π° Haar Cascades.
ΠΠ°ΡΠΊΠ°Π΄ΠΈΡΠ΅ Π½Π° Π₯Π°Π°Ρ ΡΠ΅ ΠΊΠ°ΡΠΊΠ°Π΄Π½ΠΈ ΠΊΠ»Π°ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΈ ΠΊΠΎΠΈ ΡΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈ ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΡΠ΅Ρ Π½ΠΈΠΊΠ°ΡΠ° Π½Π° Π±ΡΠ°Π½ΠΎΠ²ΠΈΠ΄Π½ΠΈ Π₯Π°Π°ΡΠΎΠ²ΠΈ. Π’ΠΈΠ΅ Π³ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°Π°Ρ ΠΏΠΈΠΊΡΠ΅Π»ΠΈΡΠ΅ Π½Π° ΡΠ»ΠΈΠΊΠ°ΡΠ° Π·Π° Π΄Π° ΠΎΡΠΊΡΠΈΡΠ°Ρ ΠΎΠ΄ΡΠ΅Π΄Π΅Π½ΠΈ ΠΊΠ°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ. ΠΠ° Π΄Π° Π΄ΠΎΠ·Π½Π°Π΅ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ Π·Π° Haar Cascades, Π²Π΅ ΠΌΠΎΠ»ΠΈΠΌΠ΅ ΡΠ»Π΅Π΄Π΅ΡΠ΅ Π³ΠΈ Π»ΠΈΠ½ΠΊΠΎΠ²ΠΈΡΠ΅ ΠΏΠΎΠ΄ΠΎΠ»Ρ.
ΠΡΠ΅Π·Π΅ΠΌΠ΅ΡΠ΅ Π²Π΅ΡΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈ ΠΊΠ°ΡΠΊΠ°Π΄ΠΈ
ΠΠ° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΠ²Π°, ΡΡΠ΅Π±Π° Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΊΠ»Π°ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΠΈ Π΄Π° Π³ΠΎ Π½Π°Ρ ΡΠ°Π½ΠΈΡΠ΅ ΡΠΎ Π²Π΅ΡΠ΅ ΠΎΠ±ΡΡΠ΅Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° (Π²ΡΡΠΊΠ°ΡΠ° Π΅ Π΄Π°Π΄Π΅Π½Π° ΠΏΠΎΠ³ΠΎΡΠ΅). ΠΠ΅ΡΠ΅ ΡΠ° ΠΏΠΎΠ΄ΠΈΠ³Π½Π°Π² Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° pencv_haarcascade_frontalface_default.xml Π²ΠΎ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡΠΌΠΎΡ ΠΊΠ°Π΄Π΅ ΡΡΠΎ ΡΠ΅ Π½Π°ΠΎΡΠ° Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°.
harrcascade := βopencv_haarcascade_frontalface_default.xmlβclassifier := gocv.NewCascadeClassifier()classifier.Load(harrcascade)
defer classifier.Close()
ΠΠ° Π΄Π° ΠΎΡΠΊΡΠΈΠ΅ΡΠ΅ Π»ΠΈΡΠ° Π½Π° ΡΠ»ΠΈΠΊΠ°, ΡΡΠ΅Π±Π° Π΄Π° Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠΈΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ΠΎΡ
for _, r := range rects {
fmt.Println(βdetectedβ, r)
gocv.Rectangle(&img, r, color, 2)
}
package main
import (
"fmt"
"image/color"
"log"
"gocv.io/x/gocv"
)
func main() {
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil {
log.Fatalf("error opening web cam: %v", err)
}
defer webcam.Close()
img := gocv.NewMat()
defer img.Close()
window := gocv.NewWindow("webcamwindow")
defer window.Close()
harrcascade := "opencv_haarcascade_frontalface_default.xml"
classifier := gocv.NewCascadeClassifier()
classifier.Load(harrcascade)
defer classifier.Close()
color := color.RGBA{0, 255, 0, 0}
for {
if ok := webcam.Read(&img); !ok || img.Empty() {
log.Println("Unable to read from the device")
continue
}
rects := classifier.DetectMultiScale(img)
for _, r := range rects {
fmt.Println("detected", r)
gocv.Rectangle(&img, r, color, 3)
}
window.IMShow(img)
window.WaitKey(50)
}
}
Π... Π΄Π°, ΡΓ¨ ΡΡΠΏΠ΅Π°! Π‘Π΅Π³Π° ΠΈΠΌΠ°ΠΌΠ΅ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π΅Π½ ΡΠΈΡΡΠ΅ΠΌ Π·Π° ΠΏΡΠ΅ΠΏΠΎΠ·Π½Π°Π²Π°ΡΠ΅ Π»ΠΈΡΠ΅ Π½Π°ΠΏΠΈΡΠ°Π½ Π²ΠΎ Go. ΠΠ°ΡΠΊΠΎΡΠΎ ΠΏΠ»Π°Π½ΠΈΡΠ°ΠΌ Π΄Π° Π³ΠΈ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΠΌ ΠΎΠ²ΠΈΠ΅ Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈ ΠΈ Π΄Π° ΡΠΎΠ·Π΄Π°Π΄Π°ΠΌ Π½ΠΎΠ²ΠΈ ΠΊΡΠ» ΡΠ°Π±ΠΎΡΠΈ ΡΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠ°ΡΠ΅ Π½Π° Go ΠΈ OpenCV.
ΠΠΊΠΎ ΡΡΠ΅ Π·Π°ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠΈΡΠ°Π½ΠΈ, Π²Π΅ ΠΌΠΎΠ»ΠΈΠΌΠ΅ ΠΎΡΠ΅Π½Π΅ΡΠ΅
ΠΠΈ Π±Π»Π°Π³ΠΎΠ΄Π°ΡΠΈΠΌΠ΅ ΡΡΠΎ ΡΠ° ΠΏΡΠΎΡΠΈΡΠ°Π²ΡΠ΅ ΡΡΠ°ΡΠΈΡΠ°ΡΠ°!
Skillbox ΠΏΡΠ΅ΠΏΠΎΡΠ°ΡΡΠ²Π°:
- ΠΠ²Π΅Π³ΠΎΠ΄ΠΈΡΠ΅Π½ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅Π½ ΠΊΡΡΡ
βΠΠ°Ρ ΡΡΠΌ PRO Π²Π΅Π±-ΡΠ°Π·Π²ΠΈΠ²Π°Ρβ .- ΠΠ΄ΡΠΊΠ°ΡΠΈΠ²Π΅Π½ ΠΎΠ½Π»Π°ΡΠ½ ΠΊΡΡΡ
βΠΡΠΎΡΠ΅ΡΠΈΡΠ° Java ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ΅Ρβ .- ΠΡΠ°ΠΊΡΠΈΡΠ΅Π½ Π³ΠΎΠ΄ΠΈΡΠ΅Π½ ΠΊΡΡΡ
βΠΡΠΎΠ³ΡΠ°ΠΌΠ΅Ρ Π½Π° PHP ΠΎΠ΄ 0 Π΄ΠΎ PROβ .
ΠΠ·Π²ΠΎΡ: www.habr.com