I am currently implementing a connected components algorithm and the last step of the algorithm requires me to enclose the objects I found in a box. I have attempted to enclose an object in a box and this is the result:
As you can see some of them seem to be enclosed in a box. Some of the lines of the box are not seen unless I stretch the windows of the imshow function's output and also some of them have color when I expected a line with a shade of gray.
My question is: Is the object really getting enclosed since I remember when I ran a similar code of mine into a different OS the lines with color are not see at all but are seen in my computer. Additionally, why are some of the lines in a different color given that I was expecting a shade of gray.
Mat src, src_gray;
Mat dst, detected_edges;
const char* window_name = "THRESHOLDED IMAGE";
/**
* #function connectedComponent
*/
static void connectedComponent(int, void*)
{
Mat test; //dummy
Mat sub;
int newObject = 0;
int zeroTest = 0, nonZero = 0;
int arr[5] = {0,0,0,0,0};
/// Reduce noise with a kernel 3x3
blur( src_gray,detected_edges, Size(3,3) ); //filtering out of noise
namedWindow("INITIAL", WINDOW_NORMAL);
imshow("INITIAL",detected_edges);
resizeWindow("INITIAL", 300, 300);
threshold(detected_edges, detected_edges, 0,255, THRESH_BINARY | THRESH_OTSU);
int** newSub = new int*[detected_edges.rows];
for(int i = 0; i < detected_edges.rows; i++)
newSub[i] = new int[detected_edges.cols];
for(int i = 0; i < detected_edges.rows; i++){
for(int j = 0; j < detected_edges.cols; j++){
newSub[i][j] = 0;
}
}
/*INITIAL MARKING LOOP*/
for(int i = 0; i < detected_edges.rows; i++){
for(int j = 0; j < detected_edges.cols; j++){
if(detected_edges.at<uchar>(i,j) == 0){
if(i-1 < 0 && j-1 < 0){
newObject = newObject + 1; //no values
newSub[i][j] = newObject;
}else if(i-1 >= 0 && j-1 < 0){
if(newSub[i-1][j] != 0){
newSub[i][j] = newSub[i-1][j]; //only up has value
}else{
newObject = newObject + 1; //no values
newSub[i][j] = newObject;
}
}else if(i-1 < 0 && j-1 >= 0){
if(newSub[i-1][j] != 0){
newSub[i][j] = newSub[i-1][j]; //only left has value
}else{
newObject = newObject + 1; //no values
newSub[i][j] = newObject;
}
}else{
if(newSub[i-1][j] == 0 && newSub[i][j-1] == 0){
newObject = newObject + 1; //no values
newSub[i][j] = newObject;
}else if(newSub[i-1][j] == newSub[i][j-1]){ //same value
newSub[i][j] = newSub[i-1][j];
}else if((newSub[i-1][j] != 0 && newSub[i][j-1] == 0)){
newSub[i][j] = newSub[i-1][j]; //only up has value
}else if(newSub[i-1][j] == 0 && newSub[i][j-1] != 0 ){
newSub[i][j] = newSub[i][j-1]; //only left has value
}else if(newSub[i-1][j] != newSub[i][j-1]){
newSub[i][j] = newSub[i-1][j]; //different values follow upper's value
}
}
}
}
}
int a = 1;
int maxRows = detected_edges.rows;
int maxCols = detected_edges.cols;
/*CONNECTING PIXELS RIGHT-BOTTOM*/
while(a < newObject){
int update = 0;
for(int i = 0; i < maxRows; i++){
for(int j = 0; j < maxCols; j++){
if(newSub[i][j] == a){
if(i+1 < maxRows && j+1 < maxCols){
if(newSub[i][j+1] > a){ //both points allowed
int value = newSub[i][j+1]; //get the value I need to replace
for(int h = 0; h < maxRows; h++){
for(int k = 0; k < maxCols; k++){
if(newSub[h][k] == value){ //replace all instances of that value
newSub[h][k] = a;
}
}
}
update = 1;
}
if(newSub[i+1][j] > a){ //both points allowed
int value = newSub[i+1][j]; //get the value I need to replace
for(int h = 0; h < maxRows; h++){
for(int k = 0; k < maxCols; k++){
if(newSub[h][k] == value){
newSub[h][k] = a; //replace all instances of that value
}
}
}
update = 1;
}
}else if(i+1 > maxRows && j+1 < maxCols){
if(newSub[i][j+1] > a){ //bottom is not allowed
int value = newSub[i][j+1]; //get the value I need to replace
for(int h = 0; h < maxRows; h++){
for(int k = 0; k < maxCols; k++){
if(newSub[h][k] == value){
newSub[h][k] = a; //replace all instances of that value
}
}
}
update = 1;
}
}else if(i+1 < maxRows && j+1 > maxCols){
if(newSub[i+1][j] > a){ //right is not allowed
int value = newSub[i+1][j]; //get the value I need to replace
for(int h = 0; h < maxRows; h++){
for(int k = 0; k < maxCols; k++){
if(newSub[h][k] == value){ //replace all instances of that value
newSub[h][k] = a;
}
}
}
update = 1;
}
}
}
}
}
a++;
}
/*CONNECTING PIXELS LEFT-TOP*/
a = newObject;
while(a > 0){
int update = 0;
for(int i = maxRows-1; i > 0; i--){
for(int j = maxCols-1; j > 0 ; j--){
if(newSub[i][j] == a){
if(i-1 >= 0 && j-1 >= 0){
if(newSub[i][j-1] > a){ //both points allowed
int value = newSub[i][j-1]; //get the value I need to replace
for(int h = 0; h < maxRows; h++){
for(int k = 0; k < maxCols; k++){
if(newSub[h][k] == value){
newSub[h][k] = a;
}
}
}
update = 1;
}
if(newSub[i-1][j] > a){
int value = newSub[i-1][j]; //get the value I need to replace
for(int h = 0; h < maxRows; h++){
for(int k = 0; k < maxCols; k++){
if(newSub[h][k] == value){ //replace all instances of that value
newSub[h][k] = a;
}
}
}
update = 1;
}
}else if(i-1 >= 0 && j-1 < 0){
if(newSub[i][j-1] > a){ //left is not allowed
int value = newSub[i][j-1]; //get the value I need to replace
for(int h = 0; h < maxRows; h++){
for(int k = 0; k < maxCols; k++){ //replace all instances of that value
if(newSub[h][k] == value){
newSub[h][k] = a;
}
}
}
update = 1;
}
}else if(i-1 < 0 && j-1 >= 0){
if(newSub[i-1][j] > a){ //top is not allowed
int value = newSub[i-1][j]; //get the value I need to replace
for(int h = 0; h < maxRows; h++){
for(int k = 0; k < maxCols; k++){ //replace all instances of that value
if(newSub[h][k] == value){
newSub[h][k] = a;
}
}
}
update = 1;
}
}
}
}
}
a--;
}
for(int i = 0; i < maxRows; i++){
for(int j = 0; j < maxCols; j++){
int check = 0;
if(newSub[i][j] != 0){
for(int k = 0; k < 5; k++){
if(newSub[i][j] == arr[k]){ //check if there is an instance of the value in the given array of values
check = 1;
break;
}
}
if(check == 0){
for(int r = 0; r < 5; r++){
if(arr[r] == 0){
arr[r] = newSub[i][j]; //if new value is found add to array
break;
}
}
}
}
}
}
/*
I HAVE AN ARRAY CONTAINING ALL VALUES
**/
src.copyTo( sub, detected_edges);
sub = Scalar::all(0);
/*SET AN INTENSITY FOR CORRESPONDING VALUES*/
int intensity = 50;
a = 0;
while(a < 5){
int update = 0;
for(int i = 0; i < maxRows; i++){
for(int j = 0; j < maxCols; j++){
if(newSub[i][j] == arr[a]){
sub.at<uchar>(i,j) = intensity;
}
}
}
a++;
intensity = intensity + 50;
}
a = 250;
/*GETTING MIN-MAX COORDINATES*/
while(a >= 50){
int setter = 0;
int minRow = 0;
int minCol = 0;
int maxRow = 0;
int maxCol = 0;
for(int i = 0; i < maxRows; i++){
for(int j = 0; j < maxCols; j++){
if(sub.at<uchar>(i,j) == a){
if(setter == 0){
minRow = i;
minCol = j;
maxRow = i;
maxCol = j;
setter = 1;
}else{
if(i <= minRow){
minRow = i;
}
else{
if(i > maxRow){
maxRow = i;
}
}
if(j <= minCol){
minCol = j;
}
else{
if(j > maxCol){
maxCol = j;
}
}
}
}
}
}
/*THIS IS WHERE I MAKE MY BOUNDING BOX*/
for(int i = minRow; i < maxRow; i++){
sub.at<uchar>(i,minCol) = 255; //set up the horizontal lines
sub.at<uchar>(i,maxCol) = 255;
}
for(int i = minCol; i < maxCol; i++){
sub.at<uchar>(minRow,i) = 255; //set up the vertical lines
sub.at<uchar>(maxRow,i) = 255;
}
a = a - 50;
}
dst = Scalar::all(0);
src.copyTo( dst, detected_edges);
imshow( window_name, dst );
namedWindow("FINAL", WINDOW_NORMAL);
imshow("FINAL",sub); //final output
resizeWindow("FINAL", 300, 300);
for(int i = 0; i < detected_edges.rows; i++)
delete[] newSub[i];
delete[] newSub;
}
/**
* #function main
*/
int main( int, char** argv )
{
/// Load an image
src = imread( argv[1] );
if( src.empty() )
{ return -1; }
/// Create a matrix of the same type and size as src (for dst)
dst.create( src.size(), src.type() );
/// Convert the image to grayscale
cvtColor( src, src_gray, COLOR_BGR2GRAY ); //grayscale for one channel for easy computation
/// Create a window
namedWindow( window_name, WINDOW_NORMAL );
resizeWindow(window_name, 300,300);
/// Show the image
connectedComponent(0, 0);
/// Wait until user exit program by pressing a key
waitKey(0);
return 0;
}
Related
I am doing Week 4 Filter-less for CS50, I get an error whne I try to compile my code
When I complie it is see this erorr.
/usr/bin/ld: /lib/x86_64-linux-gnu/Scrt1.o: in function _start': (.text+0x1b): undefined reference to main'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [: helpers] Error 1
This is my code
#include "helpers.h"
#include <math.h>
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
float r = image[i][j].rgbtRed;
float g = image[i][j].rgbtGreen;
float b = image[i][j].rgbtBlue;
float grey = round((b + g + r)/3.0);
image[i][j].rgbtRed = image[i][j].rgbtGreen = image[i][j].rgbtBlue = grey;
}
}
return;
}
// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width / 2; j++)
{
int w = width - (j + 1);
RGBTRIPLE tmp = image[i][j];
image[i][j] = image[i][w];
image[i][w] = tmp;
}
}
return;
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int b = image[i][j].rgbtBlue;
int g = image[i][j].rgbtGreen;
int r = image[i][j].rgbtRed;
int sepiaRed = round((0.393 * r) + (0.769 * g) + (0.189 * b));
int sepiaGreen = round((0.349 * r) + (0.686 * g) + (0.168 * b));
int sepiaBlue = round((0.272 * r) + (0.534 * g) + (0.131 * b));
if (sepiaRed > 255)
{
sepiaRed = 255;
}
if (sepiaGreen > 255)
{
sepiaGreen = 255;
}
if (sepiaBlue > 255)
{
sepiaBlue = 255;
}
image[i][j].rgbtBlue = sepiaBlue;
image[i][j].rgbtGreen = sepiaGreen;
image[i][j].rgbtRed = sepiaRed;
}
}
return;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE tmp[height][width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
tmp[i][j] = image[i][j];
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int totalRed = 0;
int totalGreen = 0;
int totalBlue = 0;
float counter = 0.00;
for (int x = -1; x < 2; x++)
{
for (int y = -1; y < 2; y++)
{
int X = i + x;
int Y = j + y;
if (X < 0 || Y < 0 || X > (height - 1) || Y > (width - 1))
{
continue;
}
totalRed += image[X][Y].rgbtRed;
totalGreen += image[X][Y].rgbtGreen;
totalBlue += image[X][Y].rgbtBlue;
counter++;
}
tmp[i][j].rgbtRed = round(totalRed / counter);
tmp[i][j].rgbtGreen = round(totalGreen / counter);
tmp[i][j].rgbtBlue = round(totalBlue / counter);
}
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j].rgbtRed = tmp[i][j].rgbtRed;
image[i][j].rgbtGreen = tmp[i][j].rgbtGreen;
image[i][j].rgbtBlue = tmp[i][j].rgbtBlue;
}
}
return;
}
I still dont know weather I am allowed discuss Competetive Programming Doubts here, please let me know..
Can someone help me on this SPOJ question, I am getting wrong Answer:
https://www.spoj.com/problems/SPIKES/
I have tried all the test cases I could think of and the code always gives correct output.
Before posting it here, I also asked it in spoj forum but Its been two days, no one replies...
#include<bits/stdc++.h>
using namespace std;
// # = 35
// # = 64
// . = 46
// s = 115
// Using Dijkstra to find the path with minimum no. of Spikes
int n,m,j;
const int N = 100;
const int INF = 9;
vector<int> g[N];
int vis[N][N];
pair<int,int> dist[N][N];
vector<pair<int,int>> movements = {
{0,1},{0,-1},{1,0},{-1,0}
};
bool isvalid(int i, int j){
return i>=0 && j>=0 && i<n && j<m;
}
void bfs(int sourcei, int sourcej){
set<pair<int,pair<int,int>>> q;
q.insert({0,{sourcei,sourcej}});
dist[sourcei][sourcej] = {0,INF};
while(q.size()>0){
auto curr_v = *q.begin();
int curr_i = (curr_v.second).first;
int curr_j = (curr_v.second).second;
int spikes = curr_v.first;
q.erase(q.begin());
if(vis[curr_i][curr_j]) continue;
vis[curr_i][curr_j] = 1;
for(auto m : movements){
int child_i = curr_i + m.first;
int child_j = curr_j + m.second;
int spikec = spikes;
if(!isvalid(child_i,child_j)) continue;
if(g[child_i][child_j] == 115) spikec = spikes+1;
if(vis[child_i][child_j]) continue;
if(g[child_i][child_j]==35) continue;
if(dist[child_i][child_j].second > spikec){
dist[child_i][child_j] = {(dist[curr_i][curr_j].first +1),spikec};
q.insert({spikec , {child_i,child_j}});
}
}
}
}
int main(){
cin>>n>>m>>j;
int start_j,start_i;
int end_j,end_i;
for (int i = 0; i < N; ++i){
for (int j = 0; j < N; ++j){
dist[i][j].second = INF;
dist[i][j].first = 0;
}
}
for (int i = 0; i < n; ++i){
for (int j = 0; j < m; ++j){
char x; cin>>x;
g[i].push_back((int)x);
if(x=='#') {
start_i = i;
start_j = j;
}
if(x=='x'){
end_i = i;
end_j = j;
}
}
}
bfs(start_i,start_j);
// for (int i = 0; i < n; ++i){
// for (int j = 0; j < m; ++j){
// cout<<dist[i][j].first<<","<<dist[i][j].second<<" ";
// }cout<<endl;
// }
if(dist[end_i][end_j].second <= (int)j/2) cout<<"SUCCESS"<<endl;
else cout<<"IMPOSSIBLE"<<endl;
return 0;
}
The following code works if it's attached to only a single pair, but if the EA is attached to multiple pairs, it also counts the result of cross pair and results in the wrong alert.
The idea of the following code is to decide if the attached pair has the last two trade ends positively. It should not count the other pair result from the history.
void Alert_if_the_last_two_ordes_for_same_pair_was_positive()
{
double profit = 0;
int orderId = -1;
datetime lastCloseTime = 0;
int cnt = OrdersHistoryTotal();
for(int i=0; i < cnt; i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
continue;
orderId = OrderMagicNumber();
if(OrderSymbol() == Symbol() && lastCloseTime < OrderCloseTime() && orderId == 114)
{
lastCloseTime = OrderCloseTime();
profit = OrderProfit();
}
}
double profit1 = 0;
int orderId1 = -1;
datetime lastCloseTime1 = 0;
int cnt1 = OrdersHistoryTotal()-1;
for(int i1=0; i1 < cnt1; i1++)
{
if(!OrderSelect(i1, SELECT_BY_POS, MODE_HISTORY))
continue;
orderId1 = OrderMagicNumber();
if(OrderSymbol() == Symbol() && lastCloseTime1 < OrderCloseTime() && orderId1 == 114)
{
lastCloseTime1 = OrderCloseTime();
profit1 = OrderProfit();
}
}
double profit2 = 0;
int orderId2 = -1;
datetime lastCloseTime2 = 0;
int cnt2 = OrdersHistoryTotal()-2;
for(int i2=0; i2 < cnt2; i2++)
{
if(!OrderSelect(i2, SELECT_BY_POS, MODE_HISTORY))
continue;
orderId2 = OrderMagicNumber();
if(OrderSymbol() == Symbol() && lastCloseTime2 < OrderCloseTime() && orderId2 == 114)
{
lastCloseTime2 = OrderCloseTime();
profit2 = OrderProfit();
}
}
if(profit > 0 && profit1 > 0 )
{
Alert(" profit > 0 && profit1 = up for " + Symbol());
}
first I gave the following error in the code
int KK = 10;
int colors[KK];
then I wrote const int instead of kk and fixed the error
I'm using the opencv library but I'm getting an error somewhere. When i and j are 713 48, they do not give an error, but in the next cycle, i and j are 713 and 49, and they give an error code.(OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file c:\opencv\build\include\opencv2\core\mat.hpp, line 548)
the error gives in this row.
clustered.at(i,j) = (float)(colors[bestLabels.at(1,z)]);
I share the detailed code below
int KK = 10;
int colors[KK];
Mat p;
Mat bestLabels, centers;
vector<Mat> bgr, bgrBN;
split(frame_color, bgr);
Mat mask, clustered;
Mat clusteredAll = Mat::zeros(frame_color.rows, frame_color.cols, CV_32F);
for (int k = 0; k < contoursN.size(); k++)
{
mask = Mat::zeros(frame_color.rows, frame_color.cols, CV_8U);
drawContours(mask, contoursN, k, CV_RGB(255,255,255), CV_FILLED);
clustered = Mat::zeros(frame_color.rows, frame_color.cols, CV_32F);
int A = 0;
for (int i = 0; i < frame_color.rows; i++)
for (int j = 0; j < frame_color.cols; j++)
if (mask.at<uchar>(i,j) != 0)
A++;
if (A > 20)
{
p = Mat::zeros(A, G, CV_32F);
double moy = 0;
int z = 0;
for (int i = 0; i < frame_color.rows; i++)
{
for (int j = 0; j < frame_color.cols; j++)
{
if (mask.at<uchar>(i,j) != 0)
{
p.at<float>(z,0) = bgr[0].data[i*frame_color.cols+j] / 255.0;
p.at<float>(z,1) = bgr[1].data[i*frame_color.cols+j] / 255.0;
p.at<float>(z,2) = bgr[2].data[i*frame_color.cols+j] / 255.0;
z++;
moy = moy + frame.at<uchar>(i,j);
}
}
}
moy = moy/z;
double var = 0;
for (int i = 0; i < frame_color.rows; i++)
for (int j = 0; j < frame_color.cols; j++)
if (mask.at<uchar>(i,j) != 0)
var = var+(frame.at<uchar>(i,j) - moy)*(frame.at<uchar>(i,j) - moy);
var = var/(z*z);
int K = 1 + log(1+(A/A0)+(var/var0));
kmeans(p, K, bestLabels, TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0), 3, KMEANS_PP_CENTERS, centers);
for(int i=0; i<KK; i++)
colors[i] = 255/(i+1);
z = 0;
for (int i = 0; i < frame_color.rows; i++)
{
for (int j = 0; j < frame_color.cols; j++)
{
if (mask.at<uchar>(i,j) != 0)
{
clustered.at<float>(i,j) = (float)(colors[bestLabels.at<int>(1,z)]);
z++;
}
}
}
clusteredAll = clusteredAll + clustered;
clustered.convertTo(clustered, CV_8U);
}
Example, previous low is 1.55. When next candle low is 1.66, then next next candle low is 1.44 which is lower than previous low (1.55) then do something. How to achieve it?
double previous_low = 0;
double new_low = 0;
double new_low2 = 0;
if (((previous_low==0)&&(Low[1] < Low[2])){
previous_low = Low[1];
}
if (previous_low != 0){
if (Low[1] < previous_low){
new_low2 = Low[1]; //it fail
}
if (Low[0] < previous_low){
new_low2 = Low[0]; //it works only if next 1 candle is lower than previous. It fail if next 2 candle is lower than previous_low.
}
}
It can be achive by bubblesort
public class BubbleSort
{
void bubbleSort(double arr[])
{
int n = arr.length;
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
{
System.out.print("first value :"+arr[j]+" greater than" +"previos :"+arr[j+1] + " ");
System.out.println();
// swap arr[j+1] and arr[i]
double temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
/* Prints the array */
void printArray(double arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
// Driver method to test above
public static void main(String args[])
{
BubbleSort ob = new BubbleSort();
double arr[] = {1.66, 1.55, 1.44};
ob.bubbleSort(arr);
System.out.println("Sorted array");
ob.printArray(arr);
}
}