|
import java.awt._ |
|
import java.awt.image.{BufferedImage, DataBufferByte} |
|
import javax.swing._ |
|
|
|
import org.opencv.core.{Point, _} |
|
import org.opencv.imgproc.Imgproc |
|
import org.opencv.objdetect.CascadeClassifier |
|
import org.opencv.videoio.VideoCapture |
|
|
|
import scala.reflect._ |
|
|
|
/* |
|
* Draws 4 views of WebCam: |
|
* - Original |
|
* - With face detection |
|
* - with Canny filter |
|
- With ThreshHold filter |
|
*/ |
|
object WebCamView { |
|
lazy val frame = new JFrame() |
|
lazy val lOriginal = new JLabel() |
|
lazy val lFaces = new JLabel() |
|
lazy val lCanny = new JLabel() |
|
lazy val lThreshHold = new JLabel() |
|
lazy val faceDetector = new CascadeClassifier(getClass.getResource("/lbpcascade_frontalface.xml").getPath) |
|
lazy val c = new VideoCapture() |
|
|
|
lazy val cannySlider1 = new JSlider(0, 0, 400, 200) |
|
lazy val cannySlider2 = new JSlider(0, 0, 400, 300) |
|
|
|
lazy val thrashHoldSlider1 = new JSlider(0, 0, 255, 110) |
|
lazy val thrashHoldSlider2 = new JSlider(0, 0, 255, 150) |
|
|
|
def run() { |
|
println(s"\nRunning ${classTag[this.type].toString.replace("$", "")}") |
|
|
|
|
|
c.open(0) |
|
|
|
val mat = new Mat() |
|
val mat2 = new Mat() |
|
val mFace = new Mat() |
|
val mCanny = new Mat() |
|
val mTheshHold = new Mat() |
|
println(s"isOpened = ${c.isOpened}") |
|
|
|
showGui() |
|
|
|
while (c.grab()) { |
|
c.retrieve(mat) |
|
updateImage(mat, lOriginal) |
|
mat.copyTo(mFace) |
|
|
|
markFaces(mFace) |
|
updateImage(mFace, lFaces) |
|
|
|
Imgproc.Canny(mat, mCanny, cannySlider1.getValue, cannySlider2.getValue) |
|
updateImage(mCanny, lCanny) |
|
|
|
Imgproc.threshold(mat, mTheshHold, thrashHoldSlider1.getValue, thrashHoldSlider2.getValue, Imgproc.THRESH_BINARY) |
|
updateImage(mTheshHold, lThreshHold) |
|
} |
|
|
|
c.release() |
|
} |
|
|
|
private def showGui(): Unit = { |
|
val device = GraphicsEnvironment.getLocalGraphicsEnvironment.getScreenDevices()(0) |
|
|
|
frame.setLayout(new BorderLayout()) |
|
val pane = new JPanel(new FlowLayout()) |
|
// val scrollable = new JScrollPane(pane) |
|
val scrollable = pane |
|
|
|
pane.add(lOriginal) |
|
pane.add(lFaces) |
|
pane.add(lThreshHold) |
|
|
|
val canny = new JPanel() |
|
canny.setLayout(new BorderLayout()) |
|
canny.add(lCanny, BorderLayout.CENTER) |
|
val sliders1 = new JPanel() |
|
sliders1.setLayout(new BoxLayout(sliders1, BoxLayout.Y_AXIS)) |
|
sliders1.add(cannySlider1, BorderLayout.SOUTH) |
|
sliders1.add(cannySlider2, BorderLayout.SOUTH) |
|
canny.add(sliders1, BorderLayout.SOUTH) |
|
pane.add(canny) |
|
|
|
val threshHold = new JPanel() |
|
threshHold.setLayout(new BorderLayout()) |
|
threshHold.add(lThreshHold, BorderLayout.CENTER) |
|
val sliders2 = new JPanel() |
|
sliders2.setLayout(new BoxLayout(sliders2, BoxLayout.Y_AXIS)) |
|
sliders2.add(thrashHoldSlider1, BorderLayout.SOUTH) |
|
sliders2.add(thrashHoldSlider2, BorderLayout.SOUTH) |
|
threshHold.add(sliders2, BorderLayout.SOUTH) |
|
pane.add(threshHold) |
|
|
|
frame.add(scrollable, BorderLayout.CENTER) |
|
// frame.add(sizeSlider, BorderLayout.EAST) |
|
frame.pack() |
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) |
|
frame.setBackground(Color.BLACK) |
|
frame.setVisible(true) |
|
device.setFullScreenWindow(frame) |
|
} |
|
|
|
private def updateImage(mat: Mat, label: JLabel): Unit = { |
|
val img = Mat2BufferedImage(mat) |
|
val icon = new ImageIcon(img) |
|
|
|
label.setSize(img.getWidth(null), img.getHeight(null)) |
|
|
|
label.setIcon(icon) |
|
} |
|
|
|
def Mat2BufferedImage(m: Mat): BufferedImage = { |
|
val imageType = if (m.channels() > 1) BufferedImage.TYPE_3BYTE_BGR else BufferedImage.TYPE_BYTE_GRAY |
|
val bufferSize = m.channels() * m.cols() * m.rows() |
|
val b = new Array[Byte](bufferSize) |
|
m.get(0, 0, b) |
|
val image = new BufferedImage(m.cols(), m.rows(), imageType) |
|
val targetPixels = image.getRaster.getDataBuffer.asInstanceOf[DataBufferByte].getData() |
|
System.arraycopy(b, 0, targetPixels, 0, b.length) |
|
image |
|
} |
|
|
|
def markFaces(image: Mat): Int = { |
|
val faceDetections = new MatOfRect |
|
faceDetector.detectMultiScale(image, faceDetections) |
|
|
|
// Draw a bounding box around each face. |
|
for (rect <- faceDetections.toArray) { |
|
Imgproc.rectangle( |
|
image, |
|
new Point(rect.x, rect.y), |
|
new Point(rect.x + rect.width, |
|
rect.y + rect.height), |
|
new Scalar(0, 255, 0)) |
|
} |
|
|
|
faceDetections.toArray.size |
|
} |
|
} |