Make haar feature scale - haar-classifier

This is my code
import java.awt.image.BufferedImage;
public class HaarFeature {
public static void GetFeature(BufferedImage image){
int width = image.getWidth();
int height = image.getHeight();
//int feature_width=1*scale_width;
//int feature_height=1*scale_height;
int[][] iI = IntegralImage.convIntegralImage(image);
int white=0;
int black=0;
int feature=0;
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
if(i<(height-1) && j<(width-3)){
if(i==0 && j==0){
black=iI[i][j+3];
white=iI[i+1][j+3]-iI[i][j+3];
feature=black-white;
System.out.print(feature+" ");
}
else if(i==0){
black=iI[i][j+3]-iI[i][j-1];
white=iI[i+1][j+3]+iI[i][j-1]-iI[i][j+3]-iI[i+1][j-1];
feature=black-white;
System.out.print(feature+" ");
}
else if(j==0){
black=iI[i][j+3]-iI[i-1][j+3];
white=iI[i+1][j+3]-iI[i][j+3];
feature=black-white;
System.out.print(feature+" ");
}
else{
black=iI[i][j+3]+iI[i-1][j-1]-iI[i][j-1]-iI[i-1][j+3];
white=iI[i+1][j+3]+iI[i][j-1]-iI[i][j+3]-iI[i+1][j-1];
feature=black-white;
System.out.print(feature+" ");
}
}
}
System.out.println();
}
}
}
This code just generate one rectangle features 2px x 4px. As I know, there are so many rectangle features in haar features.
How code to make scale in haar features?
Please help me

i can help you , but i program in c++, check mi code for generate haar feature:
int sizeX = feature[i][0];
int sizeY = feature[i][1];
// Each position:
for (int x = 0; x <= frameSize-sizeX; x++) {
for (int y = 0; y <= frameSize-sizeY; y++) {
// Each size fitting within the frameSize:
for (int width = sizeX; width <= frameSize-x; width+=sizeX) {
for (int height = sizeY; height <= frameSize-y; height+=sizeY) {
count++;
}
}
}
}
This code gives the correct number of features shown in Article of Lienhart, R. and Maydt, J., "An extended set of Haar-like features for rapid object detection", ICIP02, pp. I: 900–903, 2002.

Related

How to check elements from array? Avoid overlapping of my circles and match the speed for the circle spawn behind

Hi what I am trying to achieve here is not overlap the circle moving from left to right. the x coordinate is random generated, so should I check and make sure a minimum gap there so it execute draw? If so how do I do it.
Also speed is random as well, so I want to match the speed from behind to the front one(also not going backwards) and do no overtake it.
Sorry I am doing very basic coding now, so I can't use class or array for functions.
//declare global variables
int N_CARS_IN_LANE = 30;
int MIN_GAP = 50;
float xPed;
float yPed;
float dia;
boolean isCollide=false;
float [] xPos;
float [] yPos;
float [] dias;
float [] xSpeed;
void setup() {
size(1200, 400);
background(255);
xPed=width/2;
yPed=7*height/8;
dia=height/4;
init();
}
void init() {
xPos= new float[N_CARS_IN_LANE];
yPos= new float[N_CARS_IN_LANE];
dias= new float [N_CARS_IN_LANE];
xSpeed= new float [N_CARS_IN_LANE];
for ( int i=0; i<xPos.length; i++) {
for (int k=i+1; k< N_CARS_IN_LANE; k++) {
xPos[i]= random(-150);
xPos[k]=xPos[i]-k;
yPos[i]=height/8;
dias[i]=50;
xSpeed[i]=random(10);
}
}
}
void draw() {
//reset background
background(255);
balls();
moveballs();
ballsisOffscreen();
collideballs();
}
void balls() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
if (isCollide!=true) {
fill(0, 255, 0);
circle (xPos[i], yPos[i], dias[i]);
//should I put conditions here to make sure balls are separated for a MIN_GAP when draw?
}
}
}
void moveballs() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
//for (int k=i+1; k<N_CARS_IN_LANE; k++) {
xPos[i] = xPos[i] + xSpeed[i];
}
}
//check balls draw is not overlapping? and maintain a MIN_GAP
void collideballs() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
for (int k=i+1; k< N_CARS_IN_LANE; k++) { //check elements from array?
if (isCollide&&xPos[i]!=xPos[k]) {
xSpeed[k]=xSpeed[i]; // match speed from behind to from?
}
}
}
}
boolean isCollide() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
for (int k=i+1; k< N_CARS_IN_LANE; k++) {
// distance between balls
float leftright =((xPos[i]-dias[i]/2) -(xPos[k]+dias[k]/2));
float rightleft=((xPos[k]-dias[k]/2)-(xPos[i]+dias[i]/2));
if ((leftright<MIN_GAP)&&(xPos[i]!=xPos[k])&&rightleft>MIN_GAP) {
return true;
}
}
}
return false;
}
//reset ball
void ballsisOffscreen() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
if (xPos[i]>width) {
xPos[i]=-200;
}
}
}
I'm not sure if I understud correctly what you were asking for, but I hope I did it right.
I just added the speed to the position of the ball and then checked if this moves it to close to the ball in the front of it. In that case I just set it right behind the ball in front.
But for this to work you have to know which ball is in front of the current ball.
For that you could loop through all of your balls and search for the ball whoose coordinate is closest but bigger than the current balls.
Also I think it would make your code much more readable if you used Objects for the balls. That way you also don't have to search for the next ball and it makes it easier to expand later.
Here is a version I've coded up quickly that implements the balls/cars as objects and also solves your problem with collision. I hope that helps you to fix your code [Or you just copy&paste this one ;-) ]
ArrayList<Car> cars;
int carAmount = 10;
int carSize = 50;
int gab = 5;
void setup(){
size(1200, 400);
cars = new ArrayList<Car>();
}
void draw(){
background(255);
float posLastCar = width+ carSize*2 + gab; //could also be any other big number
if(random(100) > 97 && cars.size()< carAmount){
//if there are not enought cars there is a 3% chance of a new one spaning
cars.add(new Car(carSize, gab, 100));
}
for(Car car: cars){ //loops through all cars
car.update(posLastCar);
posLastCar = car.posX; //save pos of this car for the next
}
if(cars.size() > 0){
if(cars.get(0).isAtEnd()){ //checks if first car is at the end
cars.remove(0); //then removes it
}
}
}
class Car {
float posY;
float radius;
float gab;
float posX;
float speed;
Car(float radius, float gab, float posY){
this.radius = radius;
this.gab = gab;
this.posY = posY;
speed = random(3, 10); //picks random speed between 3 and 10
// to reduce the amount of extremly slow, blocking cars
posX = 0;
}
void move(float posNextCar) {
posX += speed;
if(posX + radius + gab > posNextCar){
posX = posNextCar - radius - gab;
}
}
void update(float posNextCar){
move(posNextCar);
fill(0, 255, 0);
circle (posX, posY, radius);
}
boolean isAtEnd(){
if (posX >= width + radius){
return true;
}
return false;
}
}

How to avoid object overlapping and overtaking?

I am trying to draw circles from same y coordinate.
and creating arrays for xPos. I put the speed and xPos random, how to make sure they are not overlapping and the one behind it match the speed to the front one so it wouldn't overtake?
I have retried the code, but it still overlapping for some reason that I couldn't find out?
OK now I initialise the k with i+1, so whichever behind it.
and I ran flow chart as well, the logic looks alright, still not doing what it should being doing.
int Num=10;
float dia=50;
float[] xPos= new float[Num];
float[] xSpeed=new float[Num];
void setup() {
size(300, 300);
for (int i= 0; i<xPos.length; i++) {
xPos[i]=random(-dia*Num);
xSpeed[i]=3;
boolean overlapping=false;
for(int k=;k<xPos.length;k++){
float newPos=xPos[k];
float dist=(newPos-xPos[i]);
if(dist<dia+50){
overlapping=true;
break;
}
}
if(!overlapping){
draw();
}
}
}
void draw() {
background(255);
drawBall();
moveBall();
reset();
}
void drawBall() {
for (int i= 0; i<xPos.length; i++) {
circle(xPos[i], 50, 50);
}
}
void moveBall() {
for (int i= 0; i<xPos.length; i++) {
xPos[i]+=xSpeed[i];
}
}
void reset() {
for (int i= 0; i<xPos.length; i++) {
if (xPos[i]>width) {
xPos[i]=0;
}
}
}
how to make sure they are not overlapping
For this, you could naively check if the new position has already been taken by another such as follows (I haven't run the code, so i probably has bugs, think of it more as a pseudocode):
boolean isItTaken(float[] xPos, float newPos) {
for (int i= 0; i<xPos.length; i++) {
if (abs(newPos - xPos[i]) < circleSize) return true;
}
return false;
}
for (int i= 0; i<xPos.length; i++) {
float newPos = random(-50);
while (isItTaken(xPos, newPos)) {
newPos = random(-50);
}
}
I'm sure there are better methods though. Also I think using ArrayList is better than using a simple array.
and the one behind it match the speed to the front one so it wouldn't overtake?
You could set it as a constant number? If you want it to be random, but slower than the previous one, you could set the upper limit of the random function to be the speed of the previous one such as(again, probably buggy):
ArrayList<Float> xSpeed = new ArrayList<Float>;
for (int i= 0; i < Num; i++) {
xSpeed.push(random(2, xSpeed.get(xSpeed.length - 1)));
}

Printing out mandlebrot in ascii

I'm trying to print out the ASCII version of mandlebrot in C and it doesn't seem to be working. The main thing is changing the complex c in escapeSteps as the grid changes.
Expected result:
This is my current code for printing out the result. I think the complex c changing is the reason why it's not working but its just printing out all spaces.
The escapeSteps function checks to see if its in the mandlebrot. C is a complex struct with real and imaginary values.
//TILE_SIZE = 512 pixels
int x = 0;
int y = 0;
for (y = 0; y < TILE_SIZE; y++) {
for (x = 0; x < TILE_SIZE; x++) {
complex(c) = {(x),(y)};
if (escapeSteps(c) == 256) {
printf("*");
} else {
printf(" ");
}
}
printf("\n");
}
return 0;
}

Moving average algorithm issue

I want to smooth values in realtime. For a reason this code seems to make the microcontroller(arduino - atmel) crash or not respond at least.
This is my code
float tilttemp[] = { 1,1,1,1,1,1,1,1 };
float rolltemp[] = { 1,1,1,1,1 };
float pantemp[] = { 1,1,1,1,1 };
float tiltausgabe = 0;
float rollausgabe = 0;
float panausgabe = 0;
void trackerOutput()
{
for(int i=0; i < sizeof(tilttemp) - 1; i++)
{
tilttemp[i] = tilttemp[i+1];
}
tilttemp[sizeof(tilttemp)] = tiltAngleLP; //tiltAngleLP is a value that is available
tiltausgabe = 0;
for(int i=0; i < sizeof(tilttemp); i++)
{
tiltausgabe += tilttemp[i];
}
tiltausgabe = tiltausgabe/(sizeof(tilttemp));
Serial.print(tiltausgabe);
Serial.print(",");
Serial.print(rollausgabe);
Serial.print(",");
Serial.println(panausgabe);
}
If I leave everything but
Serial.print(tiltausgabe);
Serial.print(",");
Serial.print(rollausgabe);
Serial.print(",");
Serial.println(panausgabe);
out I get the output, so something is wrong in the first part.
You don't want sizeof. You want countof.
If you want to know what that is, it is:
#define countof(a) (sizeof(a)/sizeof((a)[0]))
and
array[ countof(array) ] = ...
will not set the last element of array.
It will set the element beyond the last element.

Simple problem moving enemy in game (C / SDL)

I'm hacking away at a simple game to teach myself C and I've come up against an infuriatingly simple problem that I haven't been able to Google an answer to.
Code follows, apologies for its noobie terribleness (criticisms appreciated!):
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#define AMOUNT_OF_ENEMIES 10
#define AMOUNT_OF_PIXELS_TO_MOVE 50.0
struct enemy
{
int alive;
SDL_Rect rect;
};
void create_enemy(struct enemy *position)
{
// Take a pointer to an array. Iterate through array looking for any 'dead' instances.
// (Re)initialise when found, ignore entirely if array is full of alive instances.
int j = 0;
while(position[j].alive == 1 && j < AMOUNT_OF_ENEMIES)
{
++j;
}
if(position[j].alive == 0)
{
position[j].alive = 1;
position[j].rect.y = 0;
}
}
void update_enemies(struct enemy *position)
{
// Iterate through a passed array looking for alive instances. If found increment vertical position,
// unless instance is at bottom of screen in which case it's marked as dead.
int j = 0;
while(j < AMOUNT_OF_ENEMIES)
{
if(position[j].alive == 1)
{
position[j].rect.y += 1;
if(position[j].rect.y > 570)
{
position[j].alive = 0;
}
}
++j;
}
}
int main(void)
{
// INITS *********************************************************************
int k;
int current_time = 0;
int previous_time = 0;
float difference_in_time = 0.0;
// Load SDL library
if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
printf("Problem, yo\n");
return 1;
}
// Setup event queue
SDL_Event event;
// Create array to store enemys, initialise it
struct enemy *enemy_array = malloc(sizeof(struct enemy) * AMOUNT_OF_ENEMIES);
int j;
for(j = 0; j < AMOUNT_OF_ENEMIES; ++j)
{
enemy_array[j].alive = 0;
enemy_array[j].rect.x = 150;
enemy_array[j].rect.y = 0;
}
// Create an array to flag keypresses, initialise it
int pressed_keys[323];
int l;
for(l = 0; l < 323; ++l)
{
pressed_keys[l] = 0;
}
// Create surfaces
SDL_Surface *screen = SDL_SetVideoMode(300, 600, 0, SDL_HWSURFACE);
int black = SDL_MapRGB(screen->format, 0, 0, 0);
SDL_Surface *tower = SDL_LoadBMP("tower.bmp");
SDL_Rect tower_rect;
tower_rect.x = 50;
tower_rect.y = 0;
tower_rect.w = 200;
tower_rect.h = 600;
SDL_Surface *dude = SDL_LoadBMP("dude.bmp");
float dude_x = 0.0;
SDL_Rect dude_rect;
dude_rect.x = 120;
dude_rect.y = 500;
dude_rect.w = 60;
dude_rect.h = 100;
SDL_Surface *enemy = SDL_LoadBMP("enemy.bmp");
// GAME LOOP *****************************************************************
while(1)
{
current_time = SDL_GetTicks();
difference_in_time = (float)(current_time - previous_time) / 1000;
previous_time = current_time;
if(SDL_PollEvent(&event))
{
if(event.key.keysym.sym == SDLK_DOWN)
{
create_enemy(enemy_array);
}
else
{
switch(event.type)
{
case SDL_QUIT:
printf("NOOOOOO\n");
SDL_FreeSurface(screen);
SDL_FreeSurface(tower);
SDL_FreeSurface(enemy);
free(enemy_array);
SDL_Quit();
return 0;
case SDL_KEYDOWN:
pressed_keys[event.key.keysym.sym] = 1;
break;
case SDL_KEYUP:
pressed_keys[event.key.keysym.sym] = 0;
break;
}
}
}
if(pressed_keys[SDLK_LEFT] && dude_rect.x > 50)
{
dude_rect.x -= (AMOUNT_OF_PIXELS_TO_MOVE * difference_in_time);
}
if(pressed_keys[SDLK_RIGHT] && dude_rect.x < 190)
{
dude_rect.x += (AMOUNT_OF_PIXELS_TO_MOVE * difference_in_time);
}
update_enemies(enemy_array);
SDL_FillRect(screen, NULL, black);
SDL_BlitSurface(tower, NULL, screen, &tower_rect);
for(k = 0; k < AMOUNT_OF_ENEMIES; ++k)
{
if(enemy_array[k].alive == 1)
{
SDL_BlitSurface(enemy, NULL, screen, &enemy_array[k].rect);
}
}
SDL_BlitSurface(dude, NULL, screen, &dude_rect);
SDL_Flip(screen);
}
return 0;
}
The issue arises at this part:
if(pressed_keys[SDLK_LEFT] && dude_rect.x > 50)
{
dude_rect.x -= (AMOUNT_OF_PIXELS_TO_MOVE * difference_in_time);
}
if(pressed_keys[SDLK_RIGHT] && dude_rect.x < 190)
{
dude_rect.x += (AMOUNT_OF_PIXELS_TO_MOVE * difference_in_time);
}
The 'dude' object moves to the left correctly, but nothing happens when the right arrow key is pressed.
Adding a printf tells me the if statement is being executed correctly. Removing difference_in_time makes it work, so it's either something to do with that variable or the operation of it and AMOUNT_OF_PIXELS_TO_MOVE.
I just can't for the life of me figure out why the former block executes correctly and the latter (which is essentially the same thing) doesn't. I'm sure it's something simple I've overlooked but I'm going insane trying to find it.
Your problem is due to rounding.
For your "dude" you are using a SDL_Rect, that uses integer coordinates (short int if I remember correct).
You configured your dude speed to 50 and if your game is running at 60fps (probably due to its simplicity and it may be much more if vsync is off) you will get each frame a movement value of 0.83333.
This value will be truncated to a int and the result will be zero, for example, if dude.x is 10 and you press right, the calculated value will be 10.83 and when truncated this will result in 10.
For left, it works because the value is rounded down, assuming again dude.x is 10, when left is pressed, on the first iteration the calculated value would be 9.17, truncating this will give you 9.
Simple, bad and Hack Solution
Increase AMOUNT_OF_PIXELS_TO_MOVE to a higher value that forces the int to increase, this will fix the problem.
Good Solution
Does not use SDL_Rect for storing your characters position, create a "MyRect" and use float values in it and only does rounding when drawing the character. Actually you only need to store the character position, so I would create a Point2D struct with only x and y and use this to keep track of characters position.

Resources