Skip to content

Commit

Permalink
Initial implementation of camera groups and multiprocessing cam server
Browse files Browse the repository at this point in the history
  • Loading branch information
IMS94 committed Oct 27, 2018
1 parent a4a9987 commit 1cd56d5
Show file tree
Hide file tree
Showing 29 changed files with 580 additions and 475 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@

import org.eduze.fyp.api.config.Startable;
import org.eduze.fyp.api.listeners.ConfigurationListener;
import org.eduze.fyp.api.model.Zone;
import org.eduze.fyp.api.model.CameraConfig;
import org.eduze.fyp.api.model.CameraGroup;
import org.eduze.fyp.api.model.PointMapping;
import org.eduze.fyp.api.model.Zone;

import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
Expand All @@ -37,6 +38,11 @@
*/
public interface ConfigurationManager extends Startable {

/**
* Adds a new camera configuration.
*
* @param cameraConfig {@link CameraConfig} to be added
*/
void addCameraConfig(CameraConfig cameraConfig);

/**
Expand Down Expand Up @@ -70,4 +76,6 @@ public interface ConfigurationManager extends Startable {
boolean isConfigured();

List<Zone> getZones();

Map<Integer, CameraGroup> getCameraGroups();
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@
*/
package org.eduze.fyp.api.listeners;

import org.eduze.fyp.api.model.CameraGroup;
import org.eduze.fyp.api.resources.PersonSnapshot;

import java.util.Date;
import java.util.List;

public interface ProcessedMapListener {

void mapProcessed(List<List<PersonSnapshot>> snapshots);
void mapProcessed(CameraGroup cameraGroup, List<List<PersonSnapshot>> snapshots);

void onFrame(List<List<PersonSnapshot>> snapshots, Date timestamp);
}
46 changes: 42 additions & 4 deletions cramp-api/src/main/java/org/eduze/fyp/api/model/CameraConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
@XmlRootElement
@Entity
@Table(name = "camera_configs")
public class CameraConfig {
public class CameraConfig implements Cloneable {

@Id
@Column(name = "id")
Expand All @@ -46,15 +46,17 @@ public class CameraConfig {
@Column(unique = true)
private int cameraId;
private String ipAndPort;
private int width;
private int height;

@Lob
@Column(columnDefinition = "LONGBLOB")
private byte[] view;

@OneToOne(mappedBy = "cameraConfig", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@OneToOne(mappedBy = "cameraConfig", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
private PointMapping pointMapping = new PointMapping();

@ManyToOne
@ManyToOne()
private CameraGroup cameraGroup;

public byte[] getView() {
Expand Down Expand Up @@ -105,7 +107,43 @@ public void setCameraGroup(CameraGroup cameraGroup) {
this.cameraGroup = cameraGroup;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}

@Override
public CameraConfig clone() {
try {
super.clone();
} catch (CloneNotSupportedException ignored) { }

CameraConfig cameraConfig = new CameraConfig();
cameraConfig.setView(getView());
cameraConfig.setCameraGroup(getCameraGroup());
cameraConfig.setPointMapping(getPointMapping().clone());
cameraConfig.setHeight(getHeight());
cameraConfig.setWidth(getWidth());
cameraConfig.setCameraId(getCameraId());
cameraConfig.setIpAndPort(getIpAndPort());
cameraConfig.setIpAndPort(getIpAndPort());

return cameraConfig;
}

public String toString() {
return String.format("{ camera : %s, ipAndPort : %s, pointMappings: %s }", cameraId, ipAndPort, pointMapping);
return String.format("{ camera : %s, ipAndPort : %s, pointMappings: %s, cameraGroup: %s }",
cameraId, ipAndPort, pointMapping, cameraGroup);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
Expand Down Expand Up @@ -33,7 +34,7 @@ public class CameraGroup {
private byte[] map;

@XmlTransient
@OneToMany(mappedBy = "cameraGroup")
@OneToMany(mappedBy = "cameraGroup", cascade = {CascadeType.REMOVE})
private Set<CameraConfig> cameraConfigs;

public int getId() {
Expand Down
20 changes: 18 additions & 2 deletions cramp-api/src/main/java/org/eduze/fyp/api/model/PointMapping.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import javax.xml.bind.annotation.XmlTransient;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* Class to represent camera space to world space mappings of reference points (4 reference points usually). Points are
Expand All @@ -38,7 +39,7 @@
@Entity
@Table(name = "point_mappings")
@JsonIgnoreProperties("cameraConfig")
public class PointMapping {
public class PointMapping implements Cloneable {

@Id
@Column(name = "id")
Expand All @@ -52,7 +53,7 @@ public class PointMapping {
private List<Point> worldSpacePoints = new ArrayList<>(4);

@XmlTransient
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinColumn(name = "camera_config_id", nullable = false)
private CameraConfig cameraConfig;

Expand Down Expand Up @@ -108,6 +109,21 @@ public void setId(int id) {
this.id = id;
}

@Override
public PointMapping clone() {
try {
super.clone();
} catch (CloneNotSupportedException ignored) { }

PointMapping pointMapping = new PointMapping();
pointMapping.setCameraConfig(getCameraConfig());
// Not sending ID since clone used for write tasks
// pointMapping.setId(getId());
pointMapping.setScreenSpacePoints(getScreenSpacePoints().stream().map(Point::clone).collect(Collectors.toList()));
pointMapping.setWorldSpacePoints(getWorldSpacePoints().stream().map(Point::clone).collect(Collectors.toList()));
return pointMapping;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Expand Down
11 changes: 10 additions & 1 deletion cramp-api/src/main/java/org/eduze/fyp/api/resources/Point.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
*
* @author Imesha Sudasingha
*/
public class Point {
public class Point implements Cloneable {
private double x;
private double y;

Expand All @@ -52,6 +52,15 @@ public void setY(double y) {
this.y = y;
}

@Override
public Point clone() {
try {
super.clone();
} catch (CloneNotSupportedException ignored) { }

return new Point(getX(), getY());
}

@Override
public String toString() {
return String.format("[%f,%f]", x, y);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.eduze.fyp.api.annotations.Mode;
import org.eduze.fyp.api.listeners.ConfigurationListener;
import org.eduze.fyp.api.model.CameraConfig;
import org.eduze.fyp.api.model.CameraGroup;
import org.eduze.fyp.api.model.PointMapping;
import org.eduze.fyp.api.model.Zone;
import org.eduze.fyp.core.db.dao.CameraConfigDAO;
Expand Down Expand Up @@ -68,12 +69,13 @@ public class ConfigurationManagerImpl implements ConfigurationManager {
private String propertiesFile;
private BufferedImage map;

private Set<Integer> cameraIds = new HashSet<>();
private Set<ConfigurationListener> configurationListeners = new HashSet<>();
private CameraConfigDAO cameraConfigDAO;
private Map<Integer, CameraConfig> cameraConfigs = new ConcurrentHashMap<>();
private Map<Integer, CameraGroup> cameraGroups = new ConcurrentHashMap<>();
// TODO: 1/5/18 If zones are deleted through UI, it is not reflected here

private List<Zone> zones = new ArrayList<>();
private CameraConfigDAO cameraConfigDAO;
private ZoneDAO zoneDAO;

public ConfigurationManagerImpl() { }
Expand All @@ -90,37 +92,46 @@ private void loadConfiguration() throws IOException {

this.cameraConfigDAO.list()
.forEach(cameraConfig -> this.cameraConfigs.put(cameraConfig.getCameraId(), cameraConfig));

this.cameraConfigDAO.cameraGroups().forEach(cameraGroup -> cameraGroups.put(cameraGroup.getId(), cameraGroup));
}

@Override
public synchronized void addCameraConfig(CameraConfig cameraConfig) {
stateManager.checkState(State.STARTED);
logger.debug("Adding camera config - {}", cameraConfig);
logger.debug("Adding camera config - {}. Total: {}", cameraConfig, cameraConfigs.size());
cameraConfigs.put(cameraConfig.getCameraId(), cameraConfig);
notifyConfigurationChange();
}

@Override
public synchronized void addPointMapping(int cameraId, PointMapping mappings) {
stateManager.checkState(State.STARTED);
cameraConfigs.get(cameraId).setPointMapping(mappings);
notifyConfigurationChange();
}

/**
* Returns the next camera ID to be taken by a camera
*
* @return next camera ID
*/
@Override
public synchronized int getNextCameraId() {
stateManager.checkState(State.STARTED);

OptionalInt max = cameraIds.stream().mapToInt(Integer::intValue).max();
OptionalInt max = cameraConfigs.keySet().stream().mapToInt(Integer::intValue).max();
int nextInt = 1;
if (max.isPresent()) {
nextInt = max.getAsInt() + 1;
}

cameraIds.add(nextInt);
return nextInt;
}

@Override
public CameraConfig getCameraConfig(int cameraId) {
return cameraConfigs.get(cameraId);
return cameraConfigs.get(cameraId).clone();
}

@Override
Expand Down Expand Up @@ -149,7 +160,7 @@ public PointMapping getPointMapping(int cameraId) {

@Override
public Set<Integer> getCameraIds() {
return cameraIds;
return cameraConfigs.keySet();
}

@Override
Expand Down Expand Up @@ -178,7 +189,8 @@ public synchronized void removeConfigurationListener(ConfigurationListener liste

@Override
public boolean isConfigured() {
return cameraIds.size() > 0 && cameraIds.size() == cameraConfigs.keySet().size();
return cameraConfigs.values().size() > 0 && cameraConfigs.values().stream()
.noneMatch(cameraConfig -> cameraConfig.getCameraGroup() == null);
}

private void notifyConfigurationChange() {
Expand Down Expand Up @@ -240,4 +252,8 @@ public void setZoneDAO(ZoneDAO zoneDAO) {
public void setCameraConfigDAO(CameraConfigDAO cameraConfigDAO) {
this.cameraConfigDAO = cameraConfigDAO;
}

public Map<Integer, CameraGroup> getCameraGroups() {
return cameraGroups;
}
}
Loading

0 comments on commit 1cd56d5

Please sign in to comment.