Java - Motion / Object detection (Human detection) using OpenCV - java

I got the video stream from cctv camera using opencv. Now I want to detect a simple motion / object from this video stream. For example, if any person come in any selected zone then rectangular border should be generated around him. I search some opencv tutorial, but I didn't got any proper solution or idea.I used the following code to display video stream.
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
public class VideoStream
{
static BufferedImage tmpImg=null;
public static void main(String args[]) throws InterruptedException
{
System.out.println("opencv start..");
// Load native library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
VideoCapture camView=new VideoCapture();
camView.open("http://192.168.1.7:80/cgi-bin/view.cgi?chn=6&u=admin&p=");
if(!camView.isOpened())
{
System.out.println("Camera Error..");
}
else
{
System.out.println("Camera successfully opened");
}
videoCamera cam=new videoCamera(camView);
//Initialize swing components
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(cam);
frame.setSize(1024,768);
frame.setVisible(true);
while(camView.isOpened())
{
cam.repaint();
}
}
}
#SuppressWarnings("serial")
class videoCamera extends JPanel
{
VideoCapture camera;
Mat mat=new Mat();
public videoCamera(VideoCapture cam)
{
camera = cam;
}
public BufferedImage Mat2BufferedImage(Mat m)
{
int type = BufferedImage.TYPE_BYTE_GRAY;
if (m.channels() > 1)
{
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = m.channels() * m.cols() * m.rows();
byte[] b = new byte[bufferSize];
m.get(0, 0, b); // get all the pixels
BufferedImage img = new BufferedImage(m.cols(), m.rows(), type);
final byte[] targetPixels = ((DataBufferByte) img.getRaster().getDataBuffer()).getData();
System.arraycopy(b, 0, targetPixels, 0, b.length);
return img;
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Mat mat = new Mat();
camera.read(mat);
BufferedImage image = Mat2BufferedImage(mat);
g.drawImage(image,0,0,image.getWidth(),image.getHeight(), null);
}
}
Can any one knows how could we do that.

please check this code, but i implement it by python
import cv2, time, pandas
from datetime import datetime
first_frame = None
status_list = [None,None]
times = []
df=pandas.DataFrame(columns=["Start","End"])
video = cv2.VideoCapture('rtsp://admin:Paxton10#10.199.27.128:554')
while True:
check, frame = video.read()
status = 0
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(21,21),0)
if first_frame is None:
first_frame=gray
continue
delta_frame=cv2.absdiff(first_frame,gray)
thresh_frame=cv2.threshold(delta_frame, 30, 255, cv2.THRESH_BINARY)[1]
thresh_frame=cv2.dilate(thresh_frame, None, iterations=2)
(cnts,_)=cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in cnts:
if cv2.contourArea(contour) < 200000:
continue
status=1
(x, y, w, h)=cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 3)
status_list.append(status)
status_list=status_list[-2:]
if status_list[-1]==1 and status_list[-2]==0:
times.append(datetime.now())
if status_list[-1]==0 and status_list[-2]==1:
times.append(datetime.now())
#cv2.imshow("Gray Frame",gray)
#cv2.imshow("Delta Frame",delta_frame)
imS = cv2.resize(thresh_frame, (640, 480))
cv2.imshow("Threshold Frame",imS)
imS = cv2.resize(frame, (640, 480))
cv2.imshow("Color Frame",imS)
#cv2.imshow("Color Frame",frame)
key=cv2.waitKey(1)
if key == ord('q'):
if status == 1:
times.append(datetime.now())
break
print(status_list)
print(times)
for i in range(0, len(times), 2):
df = df.append({"Start": times[i],"End": times[i+1]}, ignore_index=True)
df.to_csv("Times.csv")
video.release()
cv2.destroyAllWindows

Related

How can I crop Detected Face from the Video Streaming and store it in a folder using OpenCV Java?

I am using OpenCV 2.4.9, Java language and eclipse. My Face Detection code is given below. The question is how can I crop out the detected face and store it in a folder?
I've trying hard for it but couldn't get the required output.
package code03;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.VideoCapture;
import org.opencv.objdetect.CascadeClassifier;
public class VideoPanel2 extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
//***********************************************************************************************
private BufferedImage image;
int count = 1;
//***********************************************************************************************
public VideoPanel2()
{
super();
}
//***********************************************************************************************
public BufferedImage getimage()
{
return image;
}
//***********************************************************************************************
public void setimage(BufferedImage newimage)
{
image = newimage;
return;
}
//***********************************************************************************************
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if (this.image==null) return;
g.drawImage(this.image,10,492,650,43,this.image.getWidth(),this.image.getHeight(), count, count, null);
}
//***********************************************************************************************
public void DatainIt() throws Exception{
JFrame frame = new JFrame("Face Detection");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,800);
System.loadLibrary("opencv_java249");
CascadeClassifier faceDetector = new CascadeClassifier("./res/haarcascade_frontalface_alt.xml");
//CascadeClassifier faceDetector = new CascadeClassifier("./res/lbpcascade_frontalface.xml");
VideoPanel2 vidPanel = new VideoPanel2();
frame.setContentPane(vidPanel);
//BUTTON
JButton save = new JButton("Add a new Person");
//save.setBounds(2, 2, 30, 80);
JPanel pbutton = new JPanel();
pbutton.add(save);
//TextField
JTextField p_name = new JTextField(25);
frame.add(p_name);
frame.add(pbutton);
frame.setVisible(true);
save.addActionListener(this);
Mat webcam_image = new Mat();
MatToBufImg mat2Buf = new MatToBufImg();
VideoCapture capture = new VideoCapture(0);
if(capture.isOpened())
{
Thread .sleep(100); //Give time to webcam to initialize itself
while(true)
{
capture.read(webcam_image);
if(!webcam_image.empty())
{
frame.setSize(webcam_image.width()+40, webcam_image.height()+60);
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(webcam_image, faceDetections);
for(Rect rect : faceDetections.toArray())
{
Core.rectangle(webcam_image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255,0));
//Mat croppedImage = setimage(rect);
}
mat2Buf.setMatrix(webcam_image, ".jpg");
//Highgui.imwrite("webcam_image.jpg", faceDetections);
//File file = new File("Image" + "." + ".jpg");
//ImageIO.write((RenderedImage) webcam_image, ".jpg", file);
vidPanel.setimage(mat2Buf.getBufferedImage());
vidPanel.repaint();
// get the video stream
//BufferedImage bi = mat2Buf.getBufferedImage();//getimage();
//bi.getSubimage(arg0, arg1, arg2, arg3);
//File outputfile= new File("D:\\Java Project\\FaceRecognition\\src\\code03\\Face Database\\saved.jpg");
//ImageIO.write((RenderedImage) bi, "jpg", outputfile);
}
else
{
System.out.println("Problems with WebCam Capture");
break;
}
}
}//end if
capture.release();
}//end DatainIt()
//***********************************************************************************************
public static void main(String arg[]) throws Exception{
VideoPanel2 vid = new VideoPanel2();
vid.DatainIt();
}//end main
//***********************************************************************************************
public void actionPerformed(ActionEvent arg0) {
}
}//end of class
The code of other file used in this class is:
package code03;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.highgui.Highgui;
public class MatToBufImg{
Mat matrix;
MatOfByte mob;
String fileExten;
public MatToBufImg(){
}
public MatToBufImg(Mat amatrix, String fileExt){
matrix = amatrix;
fileExten = fileExt;
}
public void setMatrix(Mat amatrix, String fileExt){
matrix = amatrix;
fileExten = fileExt;
mob = new MatOfByte();
}
public BufferedImage getBufferedImage(){
Highgui.imencode(fileExten, matrix, mob);
byte[] byteArray = mob.toArray();
BufferedImage bufImage = null;
try{
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
}catch(Exception e){
e.printStackTrace();
}
return bufImage;
}
}
In your code, you are detecting Face rectangles as MatOfRect and drawing a rectangle on the video.
Core.rectangle(webcam_image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255,0));
Here, you already have the roi of the image you need. So crop the roi part of the frame as:
Mat faceROI = new Mat(webcam_image,rect);
Highgui.imwrite("Face_frameNumber_faceInImageNumber.jpeg", faceROI);
Also, please consider moving to Opencv 3.1/latest version. You will benefit from the new features such as optimisations and many algorithms which have been contributed over past year.
OPENCV 3 onwards:
Highgui is now broken to VideoIO and ImgCodecs. Also, Core.rectangle like functions has moved to ImgProc.

Using android phone camera in opencv?

Is it possible to connect your phone to your computer via USB cable and use it as webcam? I know there are plenty of software that allows it (at least for wireless), but how to use it in opencv (I am using Java)?
I think it's possible, however I did not test it. First download such an application that allows to use your phone as a webcam and then connect to it via VideoCapture(0) if it's the only webcam attached to your system. This code should be good for testing, if everything works you should see the video in a JFrame:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.opencv.core.*;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
public class JPanelOpenCV extends JPanel{
BufferedImage image;
public static void main (String args[]) throws InterruptedException{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
JPanelOpenCV t = new JPanelOpenCV();
VideoCapture camera = new VideoCapture(0);
Mat frame = new Mat();
camera.read(frame);
if(!camera.isOpened()){
System.out.println("Error");
}
else {
while(true){
if (camera.read(frame)){
BufferedImage image = t.MatToBufferedImage(frame);
t.window(image, "Original Image", 0, 0);
t.window(t.grayscale(image), "Processed Image", 40, 60);
//t.window(t.loadImage("ImageName"), "Image loaded", 0, 0);
break;
}
}
}
camera.release();
}
#Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
public JPanelOpenCV() {
}
public JPanelOpenCV(BufferedImage img) {
image = img;
}
//Show image on window
public void window(BufferedImage img, String text, int x, int y) {
JFrame frame0 = new JFrame();
frame0.getContentPane().add(new JPanelOpenCV(img));
frame0.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame0.setTitle(text);
frame0.setSize(img.getWidth(), img.getHeight() + 30);
frame0.setLocation(x, y);
frame0.setVisible(true);
}
//Load an image
public BufferedImage loadImage(String file) {
BufferedImage img;
try {
File input = new File(file);
img = ImageIO.read(input);
return img;
} catch (Exception e) {
System.out.println("erro");
}
return null;
}
//Save an image
public void saveImage(BufferedImage img) {
try {
File outputfile = new File("Images/new.png");
ImageIO.write(img, "png", outputfile);
} catch (Exception e) {
System.out.println("error");
}
}
//Grayscale filter
public BufferedImage grayscale(BufferedImage img) {
for (int i = 0; i < img.getHeight(); i++) {
for (int j = 0; j < img.getWidth(); j++) {
Color c = new Color(img.getRGB(j, i));
int red = (int) (c.getRed() * 0.299);
int green = (int) (c.getGreen() * 0.587);
int blue = (int) (c.getBlue() * 0.114);
Color newColor =
new Color(
red + green + blue,
red + green + blue,
red + green + blue);
img.setRGB(j, i, newColor.getRGB());
}
}
return img;
}
public BufferedImage MatToBufferedImage(Mat frame) {
//Mat() to BufferedImage
int type = 0;
if (frame.channels() == 1) {
type = BufferedImage.TYPE_BYTE_GRAY;
} else if (frame.channels() == 3) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
BufferedImage image = new BufferedImage(frame.width(), frame.height(), type);
WritableRaster raster = image.getRaster();
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] data = dataBuffer.getData();
frame.get(0, 0, data);
return image;
}
}
P.S. I do think your question is off-topic, too.
You can simply create camera activity and write code given
package com.techamongus.opencvcamera;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.JavaCameraView;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import java.io.File;
import java.util.List;
public class CameraActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2 {
// A tag for log output.
private static final String TAG =
CameraActivity.class.getSimpleName();
// A key for storing the index of the active camera.
private static final String STATE_CAMERA_INDEX = "cameraIndex";
// A key for storing the index of the active image size.
private static final String STATE_IMAGE_SIZE_INDEX =
"imageSizeIndex";
// An ID for items in the image size submenu.
private static final int MENU_GROUP_ID_SIZE = 2;
// The index of the active camera.
private int mCameraIndex;
// The index of the active image size.
private int mImageSizeIndex;
// Whether the active camera is front-facing.
// If so, the camera view should be mirrored.
private boolean mIsCameraFrontFacing;
// The number of cameras on the device.
private int mNumCameras;
// The camera view.
private CameraBridgeViewBase mCameraView;
// The image sizes supported by the active camera.
private List<Camera.Size> mSupportedImageSizes;
// Whether the next camera frame should be saved as a photo.
private boolean mIsPhotoPending;
// A matrix that is used when saving photos.
private Mat mBgr;
// Whether an asynchronous menu action is in progress.
// If so, menu interaction should be disabled.
private boolean mIsMenuLocked;
// The OpenCV loader callback.
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(final int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
Log.d(TAG, "OpenCV loaded successfully");
mCameraView.enableView();
mBgr = new Mat();
break;
default:
super.onManagerConnected(status);
break;
}
}
};
#SuppressLint("NewApi")
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Window window = getWindow();
window.addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (savedInstanceState != null) {
mCameraIndex = savedInstanceState.getInt(
STATE_CAMERA_INDEX, 0);
mImageSizeIndex = savedInstanceState.getInt(
STATE_IMAGE_SIZE_INDEX, 0);
} else {
mCameraIndex = 0;
mImageSizeIndex = 0;
}
final Camera camera;
if (Build.VERSION.SDK_INT >=
Build.VERSION_CODES.GINGERBREAD) {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(mCameraIndex, cameraInfo);
mIsCameraFrontFacing =
(cameraInfo.facing ==
Camera.CameraInfo.CAMERA_FACING_FRONT);
mNumCameras = Camera.getNumberOfCameras();
camera = Camera.open(mCameraIndex);
} else { // pre-Gingerbread
// Assume there is only 1 camera and it is rear-facing.
mIsCameraFrontFacing = false;
mNumCameras = 1;
camera = Camera.open();
}
final Camera.Parameters parameters = camera.getParameters();
camera.release();
mSupportedImageSizes =
parameters.getSupportedPreviewSizes();
final Camera.Size size = mSupportedImageSizes.get(mImageSizeIndex);
mCameraView = new JavaCameraView(this, mCameraIndex);
mCameraView.setMaxFrameSize(size.width, size.height);
mCameraView.setCvCameraViewListener(this);
setContentView(mCameraView);
}
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the current camera index.
savedInstanceState.putInt(STATE_CAMERA_INDEX, mCameraIndex);
// Save the current image size index.
savedInstanceState.putInt(STATE_IMAGE_SIZE_INDEX,
mImageSizeIndex);
super.onSaveInstanceState(savedInstanceState);
}
#SuppressLint("NewApi")
#Override
public void recreate() {
if (Build.VERSION.SDK_INT >=
Build.VERSION_CODES.HONEYCOMB) {
super.recreate();
} else {
finish();
startActivity(getIntent());
}
}
#Override
public void onPause() {
if (mCameraView != null) {
mCameraView.disableView();
}
super.onPause();
}
#Override
public void onResume() {
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_2_0,
this, mLoaderCallback);
mIsMenuLocked = false;
}
#Override
public void onDestroy() {
if (mCameraView != null) {
mCameraView.disableView();
}
super.onDestroy();
}
public Mat onCameraFrame(final CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
final Mat rgba = inputFrame.rgba();
if (mIsPhotoPending) {
mIsPhotoPending = false;
//takePhoto(rgba);
}
if (mIsCameraFrontFacing) {
// Mirror (horizontally flip) the preview.
Core.flip(rgba, rgba, 1);
}
return rgba;
}
Disclaimer:Check my blog link
http://www.techamongus.com/2017/03/android-camera-in-opencv.html

Error using Java OpenCV library with size

I am newly working with openCV in java on eclipse and am working on an eye tracking software, i am using a base code some one else has created and plan to tweek it but am having an error with a few lines of code and can not figure out why. here is the entire class
package have;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
class FacePanel extends JPanel{
private static final long serialVersionUID = 1L;
private BufferedImage image;
// Create a constructor method
public FacePanel(){
super();
}
/*
* Converts/writes a Mat into a BufferedImage.
*
* #param matrix Mat of type CV_8UC3 or CV_8UC1
* #return BufferedImage of type TYPE_3BYTE_BGR or TYPE_BYTE_GRAY
*/
public boolean matToBufferedImage(Mat matrix) {
MatOfByte mb=new MatOfByte();
Highgui.imencode(".jpg", matrix, mb);
try {
this.image = ImageIO.read(new ByteArrayInputStream(mb.toArray()));
} catch (IOException e) {
e.printStackTrace();
return false; // Error
}
return true; // Successful
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if (this.image==null) return;
g.drawImage(this.image,10,10,this.image.getWidth(),this.image.getHeight(), null);
}
}
class FaceDetector {
private CascadeClassifier face_cascade;
// Create a constructor method
public FaceDetector(){
// face_cascade=new CascadeClassifier("./cascades/lbpcascade_frontalface_alt.xml");
//..didn't have not much luck with the lbp
face_cascade=new CascadeClassifier("./cascades/haarcascade_frontalface_alt.xml");
if(face_cascade.empty())
{
System.out.println("--(!)Error loading A\n");
return;
}
else
{
System.out.println("Face classifier loooaaaaaded up");
}
}
public Mat detect(Mat inputframe){
Mat mRgba=new Mat();
Mat mGrey=new Mat();
MatOfRect faces = new MatOfRect();
inputframe.copyTo(mRgba);
inputframe.copyTo(mGrey);
Imgproc.cvtColor( mRgba, mGrey, Imgproc.COLOR_BGR2GRAY);
Imgproc.equalizeHist( mGrey, mGrey );
face_cascade.detectMultiScale(mGrey, faces);
System.out.println(String.format("Detected %s faces", faces.toArray().length));
for(Rect rect:faces.toArray())
{
Point center= new Point(rect.x + rect.width*0.5, rect.y + rect.height*0.5 );
//draw a blue eclipse around face
the error starts here with error code : "The constructor Size(double, double, int, int, int, Scalar) is undefined"
Size s = new Size( rect.width*0.5, rect.height*0.5), 0, 0, 360, new Scalar( 0, 0, 255 )
then here at ellipse i get an error of : "The method ellipse(Mat, RotatedRect, Scalar, int, int) in the type Core is not applicable for the arguments (Mat, Point, Size, int, int, int)
Core.ellipse( mRgba, center,s , 4, 8, 0 );
}
return mRgba;
}
}
public class Eyes {
public static void main(String arg[]) throws InterruptedException{
// Load the native library.
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//or ... System.loadLibrary("opencv_java244");
//make the JFrame
JFrame frame = new JFrame("WebCam Capture - Face detection");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FaceDetector faceDetector=new FaceDetector();
FacePanel facePanel = new FacePanel();
frame.setSize(400,400); //give the frame some arbitrary size
frame.setBackground(Color.BLUE);
frame.add(facePanel,BorderLayout.CENTER);
frame.setVisible(true);
//Open and Read from the video stream
Mat webcam_image=new Mat();
VideoCapture webCam =new VideoCapture(0);
if( webCam.isOpened())
{
Thread.sleep(500); /// This one-time delay allows the Webcam to initialize itself
while( true )
{
webCam.read(webcam_image);
if( !webcam_image.empty() )
{
Thread.sleep(200); /// This delay eases the computational load .. with little performance leakage
frame.setSize(webcam_image.width()+40,webcam_image.height()+60);
//Apply the classifier to the captured image
webcam_image=faceDetector.detect(webcam_image);
//Display the image
facePanel.matToBufferedImage(webcam_image);
facePanel.repaint();
}
else
{
System.out.println(" --(!) No captured frame from webcam !");
break;
}
}
}
webCam.release(); //release the webcam
} //end main
}
any and all help would be greatly appreciated
If you have a look at the OpenCV Java API you can see the defined constructors for Size and what parameters are required:
http://docs.opencv.org/java/org/opencv/core/Size.html
A size holds two values, height and width.
So your code:
Size s = new Size( rect.width*0.5, rect.height*0.5), 0, 0, 360, new Scalar( 0, 0, 255 )
should be:
Size s = new Size( rect.width*0.5, rect.height*0.5);
this creates a size holding half the rectangle width and half the rectangle height.
And again for the Ellipse methods:
http://docs.opencv.org/java/org/opencv/core/Core.html
There are many variations but it looks like you want to be using the following:
public static void ellipse(Mat img,
Point center,
Size axes,
double angle,
double startAngle,
double endAngle,
Scalar color)
So your code:
Core.ellipse( mRgba, center,s , 4, 8, 0 );
is likely just missing the colour scalar:
Core.ellipse( mRgba, center,s , 4, 8, 0, new Scalar(B,G,R));
Where B,G,R are doubles for each colour channel.

OPenCv- Mapping Images

I am trying to crop an face out of an image and I do that by first detecting the face then mapping the area to another image but something is wrong.
Here is my code if you could help:
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.objdetect.CascadeClassifier;
public class FaceDetector {
public static void main(String[] args) {
BufferedImage img = getImage("C:\\Users\\Yousra\\Desktop\\test4.jpg");
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.out.println("\nRunning FaceDetector");
CascadeClassifier faceDetector = new CascadeClassifier("D:\\CS\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
CascadeClassifier eyeDetector = new CascadeClassifier("D:\\CS\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml");
Mat image = Highgui
.imread("C:\\Users\\Yousra\\Desktop\\test4.jpg");
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);
if( faceDetections.toArray().length == 0){
// load("C:\\Users\\Yousra\\Desktop\\download.jpg") ){
System.out.println("not found");
}
System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
for (Rect rect : faceDetections.toArray()) {
Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
new Scalar(0, 255, 0));
}
WritableRaster cr = img.getRaster();
WritableRaster wr = img.copyData(null);
for(int b=0; b<94; b++){
for(int a=0; a<94; a++){
for(int h = faceDetections.toArray()[0].y; h< 60+ 94; h++){
for(int w = faceDetections.toArray()[0].x; w< 50+ 94; w++){
wr.setSample(b, a, 0, cr.getSample(w, h, 0));
}
}
}
}
BufferedImage img2= new BufferedImage(94, 94, BufferedImage.TYPE_INT_RGB);
img2.setData(wr);
JFrame frame = new JFrame("uiuxcu");
frame.getContentPane().add(new JLabel(new ImageIcon(img2)));
frame.pack();
frame.setVisible(true);
String filename = "ouput.png";
System.out.println(String.format("Writing %s", filename));
Highgui.imwrite(filename, image);
}
public static BufferedImage getImage(String imageName) {
try {
File input = new File(imageName);
BufferedImage image = ImageIO.read(input);
return image;
} catch (IOException ie) {
System.out.println("Error:" + ie.getMessage());
}
return null;
}}
The cropped image is not accurate at all and it doesn't show the face
why not simply use submat http://docs.opencv.org/java/org/opencv/core/Mat.html#submat(org.opencv.core.Rect)
Mat face_cropped = image.submat( faceDetections.toArray()[0] );

Fill in and detect contour rectangles in Java OpenCV

I have an initial starting image through some processing that looks like this
What I want to do it is to fill in the contours so it looks somewhat like this
and find the best fit parallelograms of the two (or more) squares which would let me get each one of the four bounding lines like this
If anyone could point me to the right functions that would help, but I can't find anything helpful. I've tried many distorted rectangle correctors but couldn't get them to work.
Heres current source code
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package javacvtesting;
import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfInt;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
/**
*
* #author Arhowk
*/
public class JavaCVTesting {
/**
* #param args the command line arguments
*//*
*/
public static BufferedImage convert(Mat m){
Mat image_tmp = m;
MatOfByte matOfByte = new MatOfByte();
Highgui.imencode(".png", image_tmp, matOfByte);
byte[] byteArray = matOfByte.toArray();
BufferedImage bufImage = null;
try {
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
} catch (Exception e) {
e.printStackTrace();
}finally{
return bufImage;
}
}
public static Mat convert(BufferedImage i){
BufferedImage image = i;
byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
Mat mat = new Mat(image.getHeight(),image.getWidth(), CvType.CV_8UC3);
mat.put(0, 0, data);
return mat;
}
public static void show(BufferedImage i){
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(new ImageIcon(i)));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat src = Highgui.imread("D:\\0_image.png");
Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2HSV);
Mat dest = new Mat();
// Mat dest = new Mat(src.width(), src.height(), src.type());
Core.inRange(src, new Scalar(58,125,0), new Scalar(256,256,256), dest);
Mat erode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3,3));
Mat dilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5));
Imgproc.erode(dest, dest, erode);
Imgproc.erode(dest, dest, erode);
Imgproc.dilate(dest, dest, dilate);
Imgproc.dilate(dest, dest, dilate);
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(dest, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
Imgproc.drawContours(dest, contours, -1, new Scalar(255,255,0));
Panel p = new Panel();
p.setImage(convert(dest));
p.show();
}
}
To determine the outer contours you may use findContours with mode RETR_EXTERNAL:
List<MatOfPoint> contours = new ArrayList<>();
Mat dest = Mat.zeros(mat.size(), CvType.CV_8UC3);
Scalar white = new Scalar(255, 255, 255));
// Find contours
Imgproc.findContours(image, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// Draw contours in dest Mat
Imgproc.drawContours(dest, contours, -1, white);
Saving the obtained Mat you will get:
To fill in the obtained contours:
for (MatOfPoint contour: contours)
Imgproc.fillPoly(dest, Arrays.asList(contour), white);
Saving the new resulting Mat you will get this:
And to find the best fit rectangle for each contour:
Scalar green = new Scalar(81, 190, 0);
for (MatOfPoint contour: contours) {
RotatedRect rotatedRect = Imgproc.minAreaRect(new MatOfPoint2f(contour.toArray()));
drawRotatedRect(dest, rotatedRect, green, 4);
}
public static void drawRotatedRect(Mat image, RotatedRect rotatedRect, Scalar color, int thickness) {
Point[] vertices = new Point[4];
rotatedRect.points(vertices);
MatOfPoint points = new MatOfPoint(vertices);
Imgproc.drawContours(image, Arrays.asList(points), -1, color, thickness);
}
Finally you get this resulting image:
sounds like you want floodfill()

Categories

Resources