I am doing a project and would like to recreate a version of the image without noise. For example, this is the original image and I would like to produce an image that only displays the badminton court lines and net. This is the code that I wrote for it: `
public SimplePicture findBC()
{
Pixel[][] pixels = img_.getPixels2D();
SimplePicture result = new SimplePicture(img_.getWidth(), img_.getHeight());
int w = img_.getWidth();
int h = img_.getHeight();
boolean bird = false;
boolean line = false;
for(int r = 0; r < h; r++)
{
for(int c = 0; c < w; c++)
{
int ori = (pixels[r][c].getRed() + pixels[r][c].getGreen() + pixels[r][c].getBlue())/3;
if(pixels[r][c].getRed() >= 200 && pixels[r][c].getGreen() >= 200 && pixels[r][c].getBlue() <= 100)
bird = true;
else
bird = false;
if(ori > 195 || ori < 30)
line = true;
else
line = false;
if(line == true)
{
Color black = new Color(0, 0, 0, 0);
result.setBasicPixel(c, r, black.getRGB());
}
else if(bird==true)
{
Color birdie = new Color(255, 255, 0);
result.setBasicPixel(c, r, birdie.getRGB());
}
else if(!bird && !line)
{
Color grey = new Color(240, 240, 240, 0);
result.setBasicPixel(c, r, grey.getRGB());
}
}
}
return result;
}`
However, when I tested the code, it results in image that is noisy from glares and the lines further away are faded. If I know what the court should look like, how do I code that to let the computer know to look for key parts and recreate a cleaner version of the image? Please and thank you :)
Related
I am working on a school project in Processing (Java Mode). We have a picture of how the game should look like.
So the task is to create a grid out of squares. Random squares should light up in red. If a red square is clicked, it should change colors to green and stay green.
What my code looks like at the moment:
Square[][] grid;
int cols = 20;
int rows = 20;
void setup() {
size(400, 400);
grid = new Square[cols][rows];
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
grid[i][j] = new Square(i*20, j*20, 20, 20);
}
}
}
void draw() {
background(0);
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
grid[i][j].display();
if (grid[i][j].x<mouseX && mouseX < grid[i][j].x + grid[i][j].w && grid[i][j].y<mouseY && mouseY < grid[i][j].y + grid[i][j].h && mousePressed) {
color col = color(0,204,0);
grid[i][j].update(col);
}
}
}
}
Class for squares:
class Square {
float x, y;
float w, h;
color c;
Square(float tempX, float tempY, float tempW, float tempH) {
x = tempX;
y = tempY;
w = tempW;
h = tempH;
c = color(0);
}
void display() {
stroke(0);
fill(c);
rect(x, y, w, h);
}
void update(color c) {
this.c = c;
}
}
So at the moment, every square you click turns green. I am not sure how to write the code, so that random squares change color to red and shuffle every 5 seconds.
Do you have any tips on how to proceed with the code or which thinking steps to take to be able to solve this task?
First, take your task:
So the task is to create a grid out of squares. Random squares should light up in red. If a red square is clicked, it should change colors to green and stay green.
and break it down:
create a grid out of squares: nicely done already !
Random squares should light up in red
If a red square is clicked
change colors to green and stay green
How do you use random numbers in Processing ?
The simplest method is using the random() method: you can pass two values and you'll get back a random number between those values.
Let's say you want to flip a coin so there's a (roughly) 50-50 change you get heads or tails. You could so something like:
if(random(0, 100) > 50){
println("head");
}else{
println("tails");
}
Could even be random(0.0, 1.0) > 0.5 for example, the idea is the same.
You could think of throwing a dice or a number of dices, etc.
Remember these are pseudo-random and in your own time can explore other pseudo random related methods such as randomGauss() and noise().
random() may be good enough for now, part 2 done :)
You're almost done with part 3:
if (grid[i][j].x<mouseX && mouseX < grid[i][j].x + grid[i][j].w && grid[i][j].y<mouseY && mouseY < grid[i][j].y + grid[i][j].h && mousePressed) {
but you need to also check if the clicked square is red.
Would nice to have some red squares to begin with. Let's assume color(204, 0, 0) is your red, you could simply add an additional check:
if(grid[i][j].c == color(204, 0, 0)){
println("red block clicked");
grid[i][j].c = color(0, 204, 0);
}
Which roughly turns your sketch into:
Square[][] grid;
int cols = 20;
int rows = 20;
final color RED = color(204, 0, 0);
final color GREEN = color(0, 204, 0);
void setup() {
size(400, 400);
grid = new Square[cols][rows];
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
grid[i][j] = new Square(i*20, j*20, 20, 20);
// roughly 50 - 50 % change a grid square will be red
if (random(0, 100) > 50) {
grid[i][j].update(RED);
}
}
}
}
void draw() {
background(0);
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
grid[i][j].display();
if (grid[i][j].x<mouseX && mouseX < grid[i][j].x + grid[i][j].w && grid[i][j].y<mouseY && mouseY < grid[i][j].y + grid[i][j].h && mousePressed) {
// if the square is red
if (grid[i][j].c == RED) {
// change colour to GREEN
grid[i][j].update(GREEN);
}
}
}
}
}
class Square {
float x, y;
float w, h;
color c;
Square(float tempX, float tempY, float tempW, float tempH) {
x = tempX;
y = tempY;
w = tempW;
h = tempH;
c = color(0);
}
void display() {
stroke(0);
fill(c);
rect(x, y, w, h);
}
void update(color c) {
this.c = c;
}
}
In terms of shuffling colours every 5 seconds I recommend:
for every 5 seconds you could use millis()
above there is an example of shuffling done in setup() though you might want to encapsulate a nested loop like that with the random condition in a void shuffle() function for example which you could easily call every 5 seconds.
note that this approach will reset green blocks to red, you might want an else in that condition to reset blocks to black (otherwise, with time, most will turn red), etc.
Have fun!
P.S. I tend to separate state data from representation. For example I would add a variable to keep track of each square state (e.g. OFF, INTERACTIVE, ACTIVATED), update a basic finite state machine, then render colours accordingly. What you have above is a tight coupling between the colour of a Square and it's state. For the homework you've got that's ok, but in the future, for more complex projects you might want to consider data flows through your program and how you represent it.
I was trying to run an OpenCV program to run a DNN on an Android device using the OpenCv DNN module with Tensorflow and an SSD. However, I keep receiving this error when I try to run the program. CvException - cv::Exception: OpenCV(4.1.0) /build/master_pack-android/opencv/modules/dnn/src/dnn.cpp:692: error: (-2.15:Assertion failed) inputs.size() == requiredOutputs in function 'getMemoryShapes' I do not know how to fix this error because as far as I know, my code to access the protobuf and protobuf text file seems correct. My code to access the variables and read from them seem correct and the other OpenCV loaders are in other classes which seem to work fine. My code to access the pb and the pbtxt file are listed below:
public Mat processFrame(Mat inputFrame) {
final int IN_WIDTH = 300;
final int IN_HEIGHT = 300;
final double IN_SCALE_FACTOR = 1;
final double MEAN_VAL = 0;
final double THRESHOLD = 0.85;
// Get a new frame
Imgproc.cvtColor(inputFrame, inputFrame, Imgproc.COLOR_RGBA2RGB);
// Forward image through network.
Mat blob = Dnn.blobFromImage(inputFrame, IN_SCALE_FACTOR, new Size(IN_WIDTH, IN_HEIGHT), new Scalar(MEAN_VAL, MEAN_VAL, MEAN_VAL), true, false);
net.setInput(blob);
List<List<Double>> blobList = new ArrayList<>();
Mat detections = net.forward();
int cols = inputFrame.cols();
int rows = inputFrame.rows();
detections = detections.reshape(1, (int) detections.total() / 7);
for (int i = 0; i < detections.rows(); ++i) {
System.out.println(detections);
double confidence = detections.get(i, 2)[0];
if (confidence > THRESHOLD) {
int classId = (int) detections.get(i, 1)[0];
int left = (int) (detections.get(i, 3)[0] * cols);
int top = (int) (detections.get(i, 4)[0] * rows);
int right = (int) (detections.get(i, 5)[0] * cols);
int bottom = (int) (detections.get(i, 6)[0] * rows);
List<Double> list = new ArrayList<>();
list.add(confidence);
list.add(Double.valueOf(left));
list.add(Double.valueOf(top));
list.add(Double.valueOf(right));
list.add(Double.valueOf(bottom));
list.add(Double.valueOf(classId));
blobList.add(list);
}
}
Collections.sort(blobList, new Comparator<List<Double>>() {
#Override
public int compare(List<Double> a, List<Double> b) {
return a.get(0) > b.get(0) ? 1 : -1;
}
});
Collections.reverse(blobList);
int maxIndex = blobList.size() > 6 ? 6 : blobList.size();
int numOfSkystone = 0;
for (int i = 0; i < 6; i++) {
List<Double> blobStuff = blobList.get(i);
String detectedObj = "";
double v = blobStuff.get(5).doubleValue();
if (v == 3.0) {
detectedObj = "Skystone";
numOfSkystone++;
} else if (v == 4.0) {
detectedObj = "Stone";
} else if (v == 2.0) {
detectedObj = "Red Foundation";
} else if (v == 1.0) {
detectedObj = "Blue Foundation";
} else {
detectedObj = "Unknown";
}
String label = detectedObj + ": " + blobStuff.get(0);
int[] baseLine = new int[1];
Size labelSize = Imgproc.getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, baseLine);
Imgproc.rectangle(inputFrame, new Point((int) blobStuff.get(1).intValue(), (int) blobStuff.get(2).intValue() - labelSize.height),
new Point((int) blobStuff.get(1).intValue() + labelSize.width, (int) blobStuff.get(2).intValue() + baseLine[0]),
new Scalar(255, 255, 255), Imgproc.FILLED);
// Write class name and confidence.
Imgproc.putText(inputFrame, label, new Point(blobStuff.get(0), blobStuff.get(2)),
FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(0, 0, 0));
}
return inputFrame;
}
As far as I know, the code for that seems correct but I feel like the error may be within the pbtxt file, but I have no clue how to fix it. The pbtxt had to be attacked as a link mainly because of the reason that it is very very long close to 5000 lines and I ran the tf_graph_ssd.py file in order to generate it. However, all the lines in that too seem correct can anyone help me understand what is going wrong with it?
PB file, Pbtxt, config: https://drive.google.com/drive/folders/19g7xnC9ekjUHeFNtgcvSn2J1ioWmrb_L
It seems that there were extraneous lines generated when trying to come up with a .pbtxt file. Deleting the first 40 lines ended up solving the problem.
I'm creating a program that reads a text file with a series of x/y coordinates and places a small square where each of them should go. The program also has to deal with another text file which has a series of x/y coordinates and a double value which represents a signal strength in decibels. When I go to launch to the program it displays a black screen with a small white rectangle in the top left corner. What is wrong with my code? I'm not getting any errors in the console. The problem is almost certainly in my coveRage.java file in the second main for loop.
first text file...
500.0 500.0
250.0 250.0
second text file
1000.0 2500.0 -143.2
1213.0 2132.0 -100.7
Main.java
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File towers = new File("towers.txt");
File readings = new File("readings.txt");
//System.out.println(new File(".").getAbsoluteFile());
Scanner towers1 = new Scanner(towers);
Scanner readings1 = new Scanner(readings);
ArrayList<Integer> towerPos = new ArrayList<Integer>();
ArrayList<Integer> readingPos = new ArrayList<Integer>();
while(towers1.hasNextDouble()) {
towerPos.add((int)towers1.nextDouble());
}
towers1.close();
while(readings1.hasNextDouble()) {
readingPos.add((int)readings1.nextDouble());
}
readings1.close();
JFrame f = new JFrame("Cellphone Coverage");
f.setVisible(true);
f.setSize(500, 500);
f.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
f.add(new CoveRage(towerPos, readingPos));
}
}
coveRage.java
public class CoveRage
extends JComponent {
private ArrayList<Integer> readingPos;
private ArrayList<Integer> towerPos;
ArrayList<Integer> towerPosis = new ArrayList<Integer>();
ArrayList<Integer> distances = new ArrayList<Integer>();
int xAxis;
int yAxis;
public CoveRage(ArrayList<Integer> towerPos, ArrayList<Integer> readingPos) {
this.towerPos = towerPos;
this.readingPos = readingPos;
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
for (int j = 0; j < towerPos.size(); j += 2) {
int xAxis = towerPos.get(j) / 10;
int yAxis = towerPos.get(j + 1) / 10;
towerPosis.add(xAxis); // adds to list for checking distance between tower and signal
towerPosis.add(yAxis);
g2.setColor(Color.black);
g2.fillRect(xAxis, yAxis, 5, 5);
}
for (int i = 0; i < readingPos.size(); i =+ 3) { // for there are still readings left take in 3 values and repeat
int xAxiss = readingPos.get(i) / 10; // grabs x axis of reading
int yAxiss = readingPos.get(i + 1) / 10; // grabs y axis of reading
int sigNal = readingPos.get(i + 2); // grabs signal strength of reading
for (int k = 0; k < towerPosis.size(); k=+2) { // for there are still readings in towerPosis
int distance = (int) Math.sqrt(Math.pow(towerPosis.get(k)-xAxiss, 2)+(Math.pow(towerPosis.get(k + 1)-yAxiss, 2))); // calulates distance between tower and reading
distances.add(distance); // add distance to arrayList
int leastDist = distances.get(0);
for (int u = 0; u < distances.size(); u++) { // for there are still distance
if (distances.get(u) < leastDist) {
leastDist = distances.get(u);
}
int expected = (int) ((int) 40*(Math.log10(1.0/leastDist)));
if (sigNal >= expected) {
g2.setColor(Color.green);
g2.fillRect(xAxiss, yAxiss, 5, 5);
} else if (sigNal <= expected - 9) {
g2.setColor(Color.red);
g2.fillRect(xAxiss, yAxiss, 5, 5);
}
}
}
}
}
}
You have a (number of) infinite loops caused by k = +2, which is the same as saying k = 2, so k never increases in size
If you change all the = + to += it will work just fine
I'm making a multi-player chopper clone in Processing. Here's my code:
ArrayList<Heli> helis = new ArrayList<Heli>();
ArrayList<Heli> permaHelis = new ArrayList<Heli>();
ArrayList<Wall> walls = new ArrayList<Wall>();
IntDict keys = new IntDict();
float speed = 3;
float loop = 0;
float distance = 20;
float place = 100;
int numDead;
PFont f;
void setup() {
size(1000, 500);
f = createFont("Trebuchet MS", 25);
textFont(f);
permaHelis.add(new Heli(place, height/2, 20, 0.1, "w", color(255, 100, 100), "Dr.Swerve"));
//permaHelis.add(new Heli(place+150, height/2, 20, 0.1, str(UP), color(255, 255, 0), "Grebbles"));
for (int i = 0; i<=permaHelis.size()-1;i++) {
helis.add(permaHelis.get(i));
}
}
void draw() {
noStroke();
background(200);
if (loop == distance) {
walls.add(new Wall(width+100, random(height), random(25, 100), speed, color(0, 255, 0)));
loop=0;
}
for (int i = 0; i<helis.size();i++) {
for (int j = 0; j<walls.size();j++) {
walls.get(j).iterate();
walls.get(j).display();
if (walls.get(j).x+walls.get(j).size<=0) {
walls.remove(i);
}
if (dist(helis.get(i).x, helis.get(i).y, walls.get(j).x, walls.get(j).y)<helis.get(i).size/2+walls.get(j).size/2||helis.get(i).y<0||helis.get(i).y+helis.get(i).size>height) {
helis.get(i).explode=true;
helis.get(i).run = false;
}
}
helis.get(i).iterate();
helis.get(i).display();
}
for (int i = 0; i < helis.size();i++) {
if (helis.get(i).run==false&&helis.get(i).dead == false) {
helis.get(i).dead = true;
numDead++;
}
}
And here's the faulty bit.
if (numDead==helis.size()) {
fill(0);
text("Restart? (Press R)", width/2, height/2);
if (keyPressed&&key=='r') {
walls = new ArrayList<Wall>();
helis = new ArrayList<Heli>();
for (int i = 0; i<=permaHelis.size()-1;i++) {
helis.add(permaHelis.get(i));
}
numDead = 0;
}
}
loop++;
}
And a little key-checker at the bottom.
void keyEvent(int pressed) {
if (key==CODED) {
keys.set(str(keyCode), pressed);
}
else {
keys.set(str(key), pressed);
}
}
void keyPressed() {
keyEvent(1);
}
void keyReleased() {
keyEvent(0);
}
So when I press R to restart, the heli scores stay, unchanging, at the top of the screen, but the helis themselves don't display. Also, the walls restart fine. The array empties and new walls come in from the right of the screen. What am I doing wrong?
Some notes:
Where you do this:
for (int i = 0; i<=permaHelis.size()-1;i++) {
helis.add(permaHelis.get(i));
}
You can instead use this:
helis.addAll(permaHelis);
In this snippet, you redisplay every wall for each heli, which isn't good (because if you have ten helis, each wall is getting displayed ten times per frame!). You could have a separate loop just for the walls list to display it.
for (int i = 0; i<helis.size();i++) {
for (int j = 0; j<walls.size();j++) {
walls.get(j).iterate();
walls.get(j).display();
I think you had a typo here. Should it be walls.remove(j);?
if (walls.get(j).x+walls.get(j).size<=0) {
walls.remove(i);
}
Finally, on to your question. I can't say for sure without the code for the classes, but what I think is happening is this. You create your permaHeli, fine. You add it to the list of normal helis, fine, but it doesn't copy the object, it only adds a reference to it. So, when you do things like helis.get(i).dead = true;, you're actually changing the original permaHeli, too! Then, when you hit R and reset it, it's clearing the list and adding an already dead heli into it. Try putting println(helis.get(i).dead); in a for loop somewhere to see if this is true. If it is, all you need to do is create a new heli instead of re-using the permaHelis list (but maybe then the permaHelis aren't useful anymore).
I have a processing game i am designing that is supposed to display a game over screen when the game is lost. Unfortuinately, the game over screen never comes up. Here is the function i have it narrowed down to:
if (lives < 1) {
background(0);
textSize(100);
text("You Lost",10,10);
delay(1000);
lives = 10;
x = (int)random(width);
y = (int)random(height / 2);
velocity = new PVector(1,random(-1.4,-0.6));
score = 0;
}
When the amount of lives goes to zero, it pauses for a second and then restarts the game.
I have tried everything i can think of, but still no luck.
So my best guess, having gotten to know the processing language 2 minutes ago is the following:
Because you set the background to black (0) the text can't be seen because it is black as well, maybe try changing the text's color to something else with the fill() method to see if that's causing the issue.
if (lives < 1) {
background(0);
textSize(100);
fill(255, 255, 255); // White text
text("You Lost",10,10);
delay(1000);
lives = 10;
...
Figured it out:
i added a piece of code at the start of my loop:
if (dflag) {
delay(2000);
dflag = false;
}
and then, i put the regular update code in an else statement after it check weather you die:
if (lives < 1) {
// for(int df = 0; df < 1000; df++) {
background(0);
textSize(100);
text("You Lost",100,100);
dflag = true;
//redraw();
lives = 10;
x = (int)random(width);
y = (int)random(height / 2);
velocity = new PVector(1,random(-1.4,-0.6));
score = 0;
} else {
textSize(13);
background(0);
stroke(255);
text(score,10,10);
String l = "";
for (int q = 0; q < lives; q++) { l += "%"; }
text(l,50,10);
strokeWeight(balld);
point(x,y);
strokeWeight(8);
line(paddlex,height - 30,paddlex + paddlew,height-30);
}