For a computer science class, I'm supposed to write a program that will find the position and the size of an unknown number of aliens in a picture like this one: http://www-bcf.usc.edu/~stejada/csci101/Pix/MARS2.jpg. I currently have the following code:
#include "Myro.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include "alien.h"
#include <vector>
using std::cout;
using std::cin;
using std::endl;
using std::vector;
void trackBlob(PicturePtr &aPic, int x, int y);
int BlobSize(PicturePtr &aPic, int x, int y, vector<int>& xLocs, vector<int>& yLocs);
vector<alien> found;
int returned;
int main()
{
returned = 0;
cout << "Pick a picture to search 0-5, or choose 6 to quit" << endl;
int selection;
cin >> selection;
PicturePtr thePic;
// Choose a picture to search
bool selecting = true;
while (selecting) {
switch (selection) {
case 0:
thePic = makePicture("MARS.jpg");
selecting = false;
break;
case 1:
thePic = makePicture("MARS1.jpg");
selecting = false;
break;
case 2:
thePic = makePicture("MARS2.jpg");
selecting = false;
break;
case 3:
thePic = makePicture("MARS3.jpg");
selecting = false;
break;
case 4:
thePic = makePicture("MARS4.jpg");
selecting = false;
break;
case 5:
thePic = makePicture("MARS6.jpg");
selecting = false;
break;
case 6:
cout << "Terminating." << endl;
return 0;
default:
cout << "Invalid input. Please try again." << endl << endl;
break;
}// end switch
} // end while
// Find the aliens
cout << endl;
cout << "Pic size: " << getHeight(thePic) * getWidth(thePic) << endl << endl;
int numGreen = 0;
for (int i = 0; i < getWidth(thePic); i++) {
for (int j = 0; j < getHeight(thePic); j++) {
Pixel pix;
pix = getPixel(thePic,i,j);
// Check for alien color
if (pix.R >= 100 && pix.R <= 120 && pix.G >= 240 && pix.G <= 255 && pix.B >= 1 && pix.B <= 15) {
trackBlob(thePic,i,j);
numGreen++;
}
else if (pix.R >= 165 && pix.R <= 185 && pix.G >= 215 && pix.G <= 235 && pix.B >= 65 && pix.B <= 85) {
trackBlob(thePic,i,j);
numGreen++;
}
else if (pix.R >= 130 && pix.R <= 155 && pix.G >= 210 && pix.G <= 230 && pix.B >= 145 && pix.B <= 175) {
trackBlob(thePic,i,j);
numGreen;
}
else if (pix.R >= 27 && pix.R <= 47 && pix.G <= 265 && pix.G >= 245 && pix.B >= 1 && pix.B <= 10) {
trackBlob(thePic,i,j);
numGreen++;
}
else if (pix.R >= 240 && pix.R <= 255 && pix.G <= 240 && pix.G >= 255 && pix.B >= 25 && pix.B <= 45) {
trackBlob(thePic,i,j);
numGreen++;
}
else if (pix.R >= 235 && pix.R <= 255 && pix.G <= 245 && pix.G >= 210 && pix.B >= 200 && pix.B <= 230) {
trackBlob(thePic,i,j);
numGreen++;
}
else if (pix.R <= 240 && pix.R >= 210 && pix.G <=255 && pix.G >= 240 && pix.B >= 1 && pix.B <= 10) {
trackBlob(thePic,i,j);
numGreen++;
}
}
}
cout << endl << endl;
cout << "Number of Aliens: " << found.size() << endl;
for (int n = 0; n < found.size(); n++) {
cout << "Position of Alien #" << n << ": (" << found[n].x << "," << found[n].y << ")" << endl;
cout << "Size of Alien #" << n << ": " << found[n].size << endl;
}
cout << endl << endl << "Number pixels tried: " << numGreen << endl << endl;
cout << "Times blob returned: " << returned << endl;
show(thePic);
return 0;
}
void trackBlob(PicturePtr &aPic, int x, int y) {
// Just to be safe
Pixel aPixel = getPixel(aPic,x,y);
//if (aPixel.R == 0 && aPixel.G == 0 && aPixel.B == 0)
//return;
// Find the size of the alien
vector<int> xLocs;
vector<int> yLocs;
int size = BlobSize(aPic,x,y,xLocs,yLocs);
cout << "Blob size: " << size << endl;
returned++;
// Make sure it's big enough to be an alien
if (size < 5) {
return;
}
alien newAlien;
// Find the position
newAlien.x = 0;
for (int i = 0; i < xLocs.size(); i++) {
newAlien.x += xLocs[i];
}
newAlien.x = newAlien.x/xLocs.size();
newAlien.y = 0;
for (int j = 0; j < yLocs.size(); j++) {
newAlien.y += yLocs[j];
}
newAlien.y = newAlien.y/yLocs.size();
found.push_back(newAlien);
}
int BlobSize(PicturePtr &aPic, int x, int y, vector<int>& xLocs, vector<int>& yLocs)
{
if (x >= getWidth(aPic) || x < 0)
return 0;
Pixel pix = getPixel(aPic,x,y);
// Just to be safe
//if (pix.R == 0 && pix.G == 0 && pix.B == 0)
//return 0;
bool isAlien = false;
if (pix.R >= 100 && pix.R <= 120 && pix.G >= 240 && pix.G <= 255 && pix.B >= 1 && pix.B <= 15)
isAlien = true;
else if (pix.R >= 165 && pix.R <= 185 && pix.G >= 215 && pix.G <= 235 && pix.B >= 65 && pix.B <= 85)
isAlien = true;
else if (pix.R >= 130 && pix.R <= 155 && pix.G >= 210 && pix.G <= 230 && pix.B >= 145 && pix.B <= 175)
isAlien = true;
else if (pix.R >= 27 && pix.R <= 47 && pix.G <= 265 && pix.G >= 245 && pix.B >= 1 && pix.B <= 10)
isAlien = true;
else if (pix.R >= 240 && pix.R <= 255 && pix.G <= 240 && pix.G >= 255 && pix.B >= 25 && pix.B <= 45)
isAlien = true;
else if (pix.R >= 235 && pix.R <= 255 && pix.G <= 245 && pix.G >= 210 && pix.B >= 200 && pix.B <= 230)
isAlien = true;
else if (pix.R <= 240 && pix.R >= 210 && pix.G <=255 && pix.G >= 240 && pix.B >= 1 && pix.B <= 10)
isAlien = true;
if (!isAlien)
return 0;
// Store the location in the position vectors
xLocs.push_back(x);
yLocs.push_back(y);
// Make sure the pixel doesn't get counted again
setPixelColor(aPic,x,y,0,0,0);
int size = 0;
for (int i = 0; i <= 2; i++) {
for (int j = 0; j <= 2; j++) {
if (i == 0 && j == 0) {
break;
}
size += BlobSize(aPic,x + (i-1), y + (j-1),xLocs,yLocs);
}
}
return 1 + size;
}
When I run the code, it says it's found several hundred "aliens." Each one it finds is bigger than the last if that's helpful. I've been staring at this for days and have no idea what's going wrong. Any help would be much appreciated.
Thanks!
First off, you should remove the comments from BlobSize() like so:
// So pixels aren't counted twice
if (pix.R == 0 && pix.G == 0 && pix.B == 0)
return 0;
Since BlobSize() changes the counted pixels to black, you need to keep those lines in your code so it doesn't count pixels twice.
Also, your for loop at the end of BlobSize() is slightly wrong. It should look like this:
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
// skip pixel at this location
if (i == 0 && j == 0) {
continue;
}
size += BlobSize(aPic,x + (i-1), y + (j-1),xLocs,yLocs);
}
}
The way that it was before would check the pixel one above and left of the pixel at the current location, see that i == 0 && j == 0, then skip checking the first column. The program would run BlobSize() on the other 6 pixels (including the one at the current location).
By the way, nice use of vectors and recursion. Sorry if I answered too late and you already turned it in. I'm turning mine in on Sunday because of the extension.
Related
I have a problem with my EA trades, now I will show you the code with a screenshot of a trade (it happens often)
I see that I was definitely wrong for how the entry below must read I put an image where it explains what I have in mind
void OnTimer()
{
//---
if (currBars != Bars){
calculate_price_levels();
//debug_levels();
check_nearest_levels();
if (is_session()){
if (Close[2] < Nearest_Up_Level && Close[1] >= Nearest_Up_Level && isAvailableOrder()){
//Print("BUY entry, Nearest_Up_Level:",Nearest_Up_Level, ",Close[2]:",Close[2], ",Close[1]:",Close[1]);
double lot = _get_lot_size (Stop_Loss);
OpenTrade(Symbol(), OP_BUY, lot);
}
if (Close[2] > Nearest_Down_Level && Close[1] <= Nearest_Down_Level && isAvailableOrder()){
//Print("SELL entry, Nearest_Down_Level:",Nearest_Down_Level, ",Close[2]:",Close[2], ",Close[1]:",Close[1]);
double lot = _get_lot_size (Stop_Loss);
OpenTrade(Symbol(), OP_SELL, lot);
}
}
currBars = Bars;
}
if (Trailing_Stop > 0) trail_sl();
// if (BE > 0) check_be();
int trades_number = _get_number_of_trades();
if (trades_number < Trades_Number_0) check_last_trade_result();
Trades_Number_0 = trades_number;
}
void check_nearest_levels(){
int size = ArraySize(Price_Levels);
for (int i = 0; i < size; i++){
if (Close[2] > Price_Levels[i] && Close[2] < Price_Levels[i + 1]){
Nearest_Down_Level = Price_Levels[i];
Nearest_Up_Level = Price_Levels[i + 1];
BUY_TP_Price = 0;
if (size > i + 2) BUY_TP_Price = Price_Levels[i + 2];
else BUY_TP_Price = Nearest_Up_Level + StepPips * Point * mp;
Next_BUY_TP_Price = 0;
if (size > i + 3) Next_BUY_TP_Price = Price_Levels[i + 3];
else Next_BUY_TP_Price = BUY_TP_Price + StepPips * Point * mp;
SELL_TP_Price = 0;
if (i >= 1) SELL_TP_Price = Price_Levels[i - 1];
else SELL_TP_Price = Nearest_Down_Level - StepPips * Point * mp;
Next_SELL_TP_Price = 0;
if (i >= 2) Next_SELL_TP_Price = Price_Levels[i - 2];
else Next_SELL_TP_Price = SELL_TP_Price - StepPips * Point * mp;
break;
}
}
}
Example of what I want to do
Here is the code. I need to be able to stop the loop when ALL 3 of the entered sides are 0, not just 1 or 2. If 1 or 2 of the entered sides are 0 then it should prompt the user again. Is there an operator that will terminate the program when ALL 3 conditions are met?
Thanks in advance!
import java.util.Scanner;
public class Program2
{
public static void main(String[] args)
{
// Read user inputs
#SuppressWarnings("resource")
Scanner key = new Scanner(System.in);
// User inputed sides of triangle
double side1, side2, side3;
// Opening messages
System.out.println("\t\t\t\t\tTriangle Identifier Program");
System.out.print("This program will tell you what type of tringle you have,");
System.out.println("\nif it is a right triangle, and the area of the triangle.");
System.out.println("Use input of 0 0 0 to terminate the program.\n");
do
{
// Get sides
System.out.print("Enter side 1 of the triangle: ");
side1 = key.nextInt();
System.out.print("Enter side 2 of the triangle: ");
side2 = key.nextInt();
System.out.print("Enter side 3 of the triangle: ");
side3 = key.nextInt();
double longest = 0;
double shorter1 = 0;
double shorter2 = 0;
if (side1 == 0 || side2 == 0 || side3 == 0)
System.out.println("These numbers do not satisfy the triangle inequality. Please try again.");
// Find the largest side
if(side1 > side2 && side1 > side3)
{
longest = side1;
shorter1 = side2;
shorter2 = side3;
}
if(side2 > side1 && side2 > side3)
{
longest = side2;
shorter1 = side1;
shorter2 = side3;
}
if(side3 > side2 && side3 > side1)
{
longest = side3;
shorter1 = side1;
shorter2 = side2;
}
if(side1 > 0 && side2 > 0 && side3 > 0)
{
if(side1==side2 && side2==side3 && side3==side1)
System.out.println("The triangle is equilateral");
if((side1==side2 && side2!=side3) || (side2==side3 && side2!=side1) || (side1==side3 && side2 !=side3))
System.out.println("The triangle is isosceles");
if(side1 != side2 && side2 != side3 && side1 != side3)
System.out.println("The triangle is scalene");
if(longest == Math.sqrt((shorter1*shorter1)+(shorter2*shorter2)))
System.out.println("The triangle is a right triangle");
else
System.out.println("The tringle is not a right triangle");
}
} while (side1 != 0 & side2 != 0 & side3 != 0);
}
}
Add another if condition to check whether all 3 are 0.
do
{
// Get sides
System.out.print("Enter side 1 of the triangle: ");
side1 = key.nextInt();
System.out.print("Enter side 2 of the triangle: ");
side2 = key.nextInt();
System.out.print("Enter side 3 of the triangle: ");
side3 = key.nextInt();
double longest = 0;
double shorter1 = 0;
double shorter2 = 0;
if (side1 == 0 && side2 == 0 && side3 == 0){
break;
} else{
if (side1 == 0 || side2 == 0 || side3 == 0)
System.out.println("These numbers do not satisfy the triangle inequality. Please try again.");
// Find the largest side
if(side1 > side2 && side1 > side3)
{
longest = side1;
shorter1 = side2;
shorter2 = side3;
}
if(side2 > side1 && side2 > side3)
{
longest = side2;
shorter1 = side1;
shorter2 = side3;
}
if(side3 > side2 && side3 > side1)
{
longest = side3;
shorter1 = side1;
shorter2 = side2;
}
if(side1 > 0 && side2 > 0 && side3 > 0)
{
if(side1==side2 && side2==side3 && side3==side1)
System.out.println("The triangle is equilateral");
if((side1==side2 && side2!=side3) || (side2==side3 && side2!=side1) || (side1==side3 && side2 !=side3))
System.out.println("The triangle is isosceles");
if(side1 != side2 && side2 != side3 && side1 != side3)
System.out.println("The triangle is scalene");
if(longest == Math.sqrt((shorter1*shorter1)+(shorter2*shorter2)))
System.out.println("The triangle is a right triangle");
else
System.out.println("The tringle is not a right triangle");
}
}
} while (side1 != 0 & side2 != 0 & side3 != 0);
This code seems working but it's not
- (IBAction)caculate:(UIButton *)sender {
int x , h;
double y , p;
x = [textDegree.text intValue ] ;
{
if ((x >= 60 ) && (x < 65)) {
y = 1;
} else if (( x >= 66) && (x < 70 )) {
y =1.50;
} else if (( x >= 70) && (x < 75 )) {
y = 2;
} else if (( x >= 75) && (x < 80 )) {
y = 2.50 ;
} else if (( x >= 80) && (x < 85 )) {
y = 3 ;
} else if (( x >= 85) && (x < 90 )) {
y = 3.50 ;
} else if (( x >= 90) && (x < 95 )) {
y = 3.75 ;
} else if (( x >= 95) && (x <= 100 )) {
y = 4 ;
} else
y = 0 ;
}
h = [textHour.text intValue];
p = y * h ;
point.text = [NSString stringWithFormat:#"%f", p];
}
when I simulate it, it take me out and says
x = [textDegree.text intValue ] ;
thread 1 :breakpoint7.1
I am trying to add a logo to a bigger image but I get the following error.
OpenCV Error: Assertion failed (0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows) in Mat, file C:\opencv246\modules\core\src\matrix.cpp, line 323
terminate called after throwing an instance of ’cv::Exception’
what(): C:\opencv246\modules\core\src\matrix.cpp:323: error: (-215) 0 <= roi.X && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows in function Mat
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application’s support team for more information.
can someone please correct my code? I have been trying to fix it for three hours but still have not been able to do it.
here is my code.
using namespace std;
using namespace cv;
int main()
{
Mat image = imread("C:\\castle.jpg",0);
Mat logo = imread("C:\\logo.jpg",0);
Mat imageROI = image(cv::Rect(385,270,logo.cols,logo.rows));
addWeighted(imageROI,1.0,logo,0.3,0.,imageROI);
namedWindow("output",CV_WINDOW_AUTOSIZE);
imshow("output",imageROI);
waitKey(0);
destroyAllWindows();
}
Your image probably doesn't have the right size. What are the dimensions in pixels of image and logo? If image.cols < 385 + logo.cols or image.rows < 270 + logo.rows you will not be able to overlap this logo on this image at this position.
( face )
( body )
Hi, i am new to image processing and openCV C/C++. I am wondering that is it possible to extract skin tone from the first image (face). And then applied to the second image (body).
In other words, user upload his face image and the program extract the skin tone from that image and apply it to the body.
Thanks,
Aisha
This is a hard problem to solve, especially given the variation of colours depending on lighting and reflection. I have worked previously on finding skin in images, and generally the Cr (chroma red) component of the YCbCr colour space stands out prominently on skin. You might be able to exploit this information to find skin regions.
Here are a couple of papers that attempt to use colour for locating human skin:
1. Interaction between hands and wearable cameras
2. Markerless inspection of augmented reality objects
For finding skin you can use one of this formulas:
1) With normilized RGB space:
for(int i = 0; i < m_image->height; ++i)
{
for(int j = 0; j < m_image->width; ++j)
{
if (m_image->nChannels == 3)
{
int valueR = (reinterpret_cast<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3 + 2];
int valueG = (reinterpret_cast<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3 + 1];
int valueB = (reinterpret_cast<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3];
float normR = static_cast<float>(valueR) / static_cast<float>(valueR + valueG + valueB);
float normG = static_cast<float>(valueG) / static_cast<float>(valueR + valueG + valueB);
float normB = static_cast<float>(valueB) / static_cast<float>(valueR + valueG + valueB);
if ((normB / normG < 1.249) &&
(( normR + normG + normB ) / ( 3 * normR ) > 0.696 ) &&
( 1/3.0 - normB/( normR + normG + normB ) > 0.014 ) &&
(normG/(3* (normR + normG + normB)) < 0.108 ))
{
//pixel is skin
}
}
}
2) in RGB space:
for(size_t i = 0; i < m_image->height; ++i)
{
for(size_t j = 0; j < m_image->width; ++j)
{
if (m_image->nChannels == 3)
{
int R = (reinterpret_cast<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3 + 2];
int G = (reinterpret_cast<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3 + 1];
int B = (reinterpret_cast<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3];
if (( R > 95) && ( G > 40 ) && ( B > 20 ) &&
(std::max(R, std::max( G, B) ) - std::min(R, std::min(G, B) ) > 15) &&
(std::abs(R - G) > 15) && (R > G) && (R > B))
{
//skin pixel
}
}
}
3) in YCrCb space:
for(size_t i = 0; i < m_image->height; ++i)
{
for(size_t j = 0; j < m_image->width; ++j)
{
if (m_image->nChannels == 3)
{
int Cr = (reinterpret_cast<uchar*>(image->imageData + i * image->widthStep))[j * 3 + 2];
int Cb = (reinterpret_cast<uchar*>(image->imageData + i * image->widthStep))[j * 3 + 1];
int Y = (reinterpret_cast<uchar*>(image->imageData + i * image->widthStep))[j * 3];
if (( Y > 80 ) && ( Cb > 85 ) && ( Cb < 135 ) &&
(Cr > 135) && (Cr < 180))
{
//skin pixel
}
}
}
}