使用opencv(Java)在视频中跟踪特定颜色
您好:)我正在使用java中的openCV库。 我有一个鼠标在轮子上运行的视频。在方向盘上,我放了一个记号笔。 我需要知道鼠标在上面运行了多少个循环。 所以要做到这一点,我需要跟踪车轮上的标记 我编写了代码,但我无法真正获得要放入标量类的特定颜色范围。 请帮帮我,这是学校的项目 这是视频的链接: 我知道视频看起来很糟糕,但这就是我所拥有的( 这是代码:使用opencv(Java)在视频中跟踪特定颜色,java,opencv,colors,pixel,scalar,Java,Opencv,Colors,Pixel,Scalar,您好:)我正在使用java中的openCV库。 我有一个鼠标在轮子上运行的视频。在方向盘上,我放了一个记号笔。 我需要知道鼠标在上面运行了多少个循环。 所以要做到这一点,我需要跟踪车轮上的标记 我编写了代码,但我无法真正获得要放入标量类的特定颜色范围。 请帮帮我,这是学校的项目 这是视频的链接: 我知道视频看起来很糟糕,但这就是我所拥有的( 这是代码: public class VideoTracker { private Panel videoPanel; private P
public class VideoTracker {
private Panel videoPanel;
private Panel hsvPanel;
private Panel thresholdPanel;
private JFrame videoFrame;
private JFrame hsvFrame;
private JFrame thresholdFrame;
private Mat frame;
private Mat hsv;
private Mat threshold;
private Mat threshold2;
private String path;
private Pixel markerDetails;
public VideoTracker(String videoPath) {
videoPanel = new Panel();
hsvPanel = new Panel();
thresholdPanel = new Panel();
videoFrame = new JFrame("Camera");
hsvFrame = new JFrame("HSV");
thresholdFrame = new JFrame("Threshold");
frame = new Mat(640,480,3);
hsv = new Mat();
threshold = new Mat();
threshold2 = new Mat();
path = videoPath;
markerDetails = new Pixel();
}
public void trackWhite() throws AWTException {
initializeJFrames();
addClickEvent();
//Read the video file
VideoCapture capture = new VideoCapture(path);
capture.set(3, 1366);
capture.set(4, 768);
capture.set(15, -2);
capture.read(frame);
videoFrame.setSize(frame.width() + 40, frame.height() + 60);
hsvFrame.setSize(frame.width() + 40, frame.height() + 60);
thresholdFrame.setSize(frame.width() + 40, frame.height() + 60);
Mat array255 = new Mat(frame.height(), frame.width(), CvType.CV_8UC1);
array255.setTo(new Scalar(255));
Mat distance = new Mat(frame.height(), frame.width(), CvType.CV_8UC1);
List<Mat> hsvList = new ArrayList<Mat>(3);
Mat circles = new Mat(); // No need (and don't know how) to initialize it.
// The function later will do it... (to a 1*N*CV_32FC3)
Scalar hsv_min = new Scalar(markerDetails.getBlue()/2 - 20 < 0 ? 0 : markerDetails.getBlue()/2 - 20,markerDetails.getGreen() - 20 < 0 ? 0 : markerDetails.getGreen() - 20 ,markerDetails.getRed() - 20 < 0 ? 0 : markerDetails.getRed() - 20); //BGR
Scalar hsv_max = new Scalar(markerDetails.getBlue()/2 + 20 < 0 ? 0 : markerDetails.getBlue()/2 + 20,markerDetails.getGreen() + 20 < 0 ? 0 : markerDetails.getGreen() + 20 ,markerDetails.getRed() + 20 < 0 ? 0 : markerDetails.getRed() + 20); //BGR
double[] data = new double[3];
if (!capture.isOpened()) {
System.err.println("Can't read video properly.");
return;
}
while (true) {
capture.read(frame);
if (!frame.empty()) {
// One way to select a range of colors by Hue
Imgproc.cvtColor(frame, hsv, Imgproc.COLOR_BGR2HSV);
Core.inRange(hsv, hsv_min, hsv_max, threshold);
Imgproc.erode(threshold, threshold, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8, 8)));
Imgproc.dilate(threshold, threshold, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8, 8)));
// Notice that the thresholds don't really work as a "distance"
// Ideally we would like to cut the image by hue and then pick just
// the area where S combined V are largest.
// Strictly speaking, this would be something like sqrt((255-S)^2+(255-V)^2)>Range
// But if we want to be "faster" we can do just (255-S)+(255-V)>Range
// Or otherwise 510-S-V>Range
// Anyhow, we do the following... Will see how fast it goes...
Core.split(hsv, hsvList); // We get 3 1D one channel Mats
Mat S = hsvList.get(1);
Mat V = hsvList.get(2);
Core.subtract(array255, S, S);
Core.subtract(array255, V, V);
S.convertTo(S, CvType.CV_32F);
V.convertTo(V, CvType.CV_32F);
Core.magnitude(S, V, distance);
//TODO: threshold2
Core.inRange(distance, new Scalar(0.0), new Scalar(200.0), threshold2);
Core.bitwise_and(threshold, threshold2, threshold);
// Apply the Hough Transform to find the circles
Imgproc.GaussianBlur(threshold, threshold, new Size(9, 9), 0, 0);
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.HoughCircles(threshold, circles, Imgproc.CV_HOUGH_GRADIENT, 2, threshold.height() / 8, 200, 100, 0, 0);
//TODO: threshold2
Imgproc.findContours(threshold, contours, threshold2, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
Imgproc.drawContours(frame, contours, -1, new Scalar(255, 0, 0), 2);
System.out.println(contours.size());
Imgproc.Canny(threshold, threshold, 500, 250);
//-- 4. Add some info to the image
Imgproc.line(frame, new org.opencv.core.Point(150, 50), new org.opencv.core.Point(202, 200), new Scalar(100, 10, 10), 3);
// Imgproc.rectangle(frame, new org.opencv.core.Point(150, 50), new org.opencv.core.Point(202, 200), new Scalar(100, 10, 10), 3);
Imgproc.circle(frame, new org.opencv.core.Point(210, 210), 10, new Scalar(100, 10, 10), 3);
data = frame.get(210, 210);
Imgproc.putText(frame, String.format("(" + String.valueOf(data[0]) + "," + String.valueOf(data[1]) + "," + String.valueOf(data[2]) + ")"),
new org.opencv.core.Point(30, 30), 3, 1.0, new Scalar(100, 10, 10, 255), 3);
//Display the image
displayTrackInVideo();
} else {
System.err.println(" -- No captured frame -- Break!");
break;
}
}
}
private void initializeJFrames() {
videoFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
videoFrame.setSize(640, 480);
videoFrame.setBounds(0, 0, videoFrame.getWidth(), videoFrame.getHeight());
videoFrame.setContentPane(videoPanel);
videoFrame.setVisible(true);
hsvFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
hsvFrame.setSize(640, 480);
hsvFrame.setBounds(300, 100, hsvFrame.getWidth() + 300, 100 + hsvFrame.getHeight());
hsvFrame.setContentPane(hsvPanel);
hsvFrame.setVisible(true);
thresholdFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thresholdFrame.setSize(640, 480);
thresholdFrame.setBounds(900, 300, hsvFrame.getWidth() + 900, 300 + hsvFrame.getHeight());
thresholdFrame.setContentPane(thresholdPanel);
thresholdFrame.setVisible(true);
}
private void addClickEvent() {
videoPanel.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent event) {
//get the mouse location
markerDetails.getMousePoint().setLocation(MouseInfo.getPointerInfo().getLocation());
int rgb = videoPanel.matToBufferedImage(frame).getRGB(markerDetails.getX(), markerDetails.getY());
Color color = new Color(rgb);
markerDetails.setRed(color.getRed());
markerDetails.setGreen(color.getGreen());
markerDetails.setBlue(color.getBlue());
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
}
private void displayTrackInVideo() {
videoPanel.setimagewithMat(frame);
hsvPanel.setimagewithMat(hsv);
thresholdPanel.setimagewithMat(threshold);
videoFrame.repaint();
hsvFrame.repaint();
thresholdFrame.repaint();
}
import java.awt.*;
public class Pixel {
private final Point mousePoint;
private int red;
private int green;
private int blue;
public Pixel(){
mousePoint = new Point();
}
public int getX(){
return mousePoint.x;
}
public int getY(){
return mousePoint.y;
}
public Point getMousePoint() {
return mousePoint;
}
public int getRed() {
return red;
}
public void setRed(int red) {
this.red = red;
}
public int getGreen() {
return green;
}
public void setGreen(int green) {
this.green = green;
}
public int getBlue() {
return blue;
}
public void setBlue(int blue) {
this.blue = blue;
}
}