Προς το περιεχόμενο
  • 0
iex

Image Processing C program for hough circle!!

Ερώτηση

 

Καλησπέρα σε όλους σας,

Αντιμετωπίζω πρόβλημα με το πως να εφαρμόσω τους μαθηματικούς τύπους και να λύσω την εξής άσκηση που σας παραθέτω. 

 

"Να δημιουργηθεί πρόγραμμα το οποίο θα δημιουργεί μια εικόνα, διαστάσεων 256x256 pixels η οποία θα αποτελείται από background  απόχρωσης 225 και θα περιέχει κύκλο,  μεταβλητής ακτίνας η οποία θα δίνεται από το πληκτρολόγιο, απόχρωσης 64. Το κέντρο του κύκλου θα βρίσκεται στο κέντρο της εικόνας."

 

Ενημερωτικά τις εικόνες που δημιουργώ τις τρέχω με το irfanview και ειναι της μορφής .raw

Επισυνάπτω και το αρχείο που είναι έτοιμη η δομή του αλλα χωρίς το συγκεκριμένο τμήμα.

(σπάω το κεφάλι μου εδώ και ώρες , ψάχνοντας και στο google αλλα δεν βρήκα κάτι μου να με καλύπτει. ) :shock:  :shock:  :shock:  :shock:  :shock:  :shock:  :shock: 

 

Σας ευχαριστώ όλους εκ των προτέρων. B)

testcode.txt

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Προτεινόμενες αναρτήσεις

  • 0

Στην if(?????) πρέπει να εκφράσεις το κριτήριο με το οποίο θα τεστάρεις εάν το τρέχων pixel ανήκει στον κύκλο ή όχι

Το κριτήριο αυτό είναι το: "Η απόσταση από κέντρο του κύκλου να είναι ίση με την ακτίνα" 

Την απόσταση θα την υπολογίσεις ώς εξής: SquareRoot((128 - ι)^2 + (128 - j)^2)
 

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Στην if(?????) πρέπει να εκφράσεις το κριτήριο με το οποίο θα τεστάρεις εάν το τρέχων pixel ανήκει στον κύκλο ή όχι

 

Το κριτήριο αυτό είναι το: "Η απόσταση από κέντρο του κύκλου να είναι ίση με την ακτίνα" 

 

Την απόσταση θα την υπολογίσεις ώς εξής: SquareRoot((128 - ι)^2 + (128 - j)^2)

 

Σε ευχαριστώ , αλλά δεν μου τρέχει .. δεν βγάζει καν αρχείο εξόδου.. ίσως να χρειάζεται κάτι ακόμη;;  :wacko:

 

Στην if(?????) πρέπει να εκφράσεις το κριτήριο με το οποίο θα τεστάρεις εάν το τρέχων pixel ανήκει στον κύκλο ή όχι

 

Το κριτήριο αυτό είναι το: "Η απόσταση από κέντρο του κύκλου να είναι ίση με την ακτίνα" 

 

Την απόσταση θα την υπολογίσεις ώς εξής: SquareRoot((128 - ι)^2 + (128 - j)^2)

 

Επίσης την ακτίνα R που θα την βάλω..?? εννοώ πως κάπου πρέπει να υπάρχει για να της δίνω τιμή..

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Ευχαριστώ πολύ για την απάντηση, το σχήμα και οι επεξηγήσεις είναι άψογες!!
Θα το δοκιμάσω αν όχι τώρα (γιατί είμαι αυπνος 30 ώρες) σίγουρα αύριο !! :-D  :-D  :-D

  • Like 1

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0
Δημοσ. (επεξεργασμένο)

Μια μικρή υλοποίηση του πρώτου τρόπου (μου είναι πιο οικείος) σε C..

 

// Draw circle to RAW file
#include <stdio.h>
#include <string.h>
#include <math.h>

#define WIDTH  	256
#define HEIGHT  256
#define CENTRE 	128
#define RADIUS	100
#define BKGRND	225	/* background */
#define	FRGRND	 65	/* foreground */

int main(void)
{
	FILE *f = NULL;

	if(!(f = fopen("TEST.RAW", "wb")))
		perror("fopen");
	else
	{
		const double maxAngle = M_PI * 2;

		double angle;

		unsigned char cImage[HEIGHT][WIDTH];

		memset(&cImage, BKGRND, sizeof(cImage));

                /* Draw circle */
		for(angle = 0.0; angle < maxAngle; angle += 0.01)
		{
			const int y = (RADIUS * sin(angle)) + CENTRE,
				  x = (RADIUS * cos(angle)) + CENTRE;

			cImage[y][x] = FRGRND;
		}

		/* Dump array to disk.. */
		if(fwrite(cImage, sizeof(unsigned char), WIDTH * HEIGHT, f) != WIDTH * HEIGHT)
			perror("fwrite");

		fclose(f);
	}

	puts("Press Enter to exit..");
	getchar();

	return 0;
}

post-41640-0-49010600-1364754293_thumb.png

Υ.Γ.

Το πρόγραμμα έχει δοκιμασθεί σε C++ Builder και μπορεί να περιέχει bugs ή άλλες αβλεψίες..

 

 

Επεξ/σία από Directx
  • Like 2

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

 

Μια μικρή υλοποίηση του πρώτου τρόπου (μου είναι πιο οικείος) σε C..

 

 

// Draw circle to RAW file
#include <stdio.h>
#include <string.h>
#include <math.h>

#define WIDTH  	256
#define HEIGHT  256
#define CENTRE 	128
#define RADIUS	100
#define BKGRND	225	/* background */
#define	FRGRND	 65	/* foreground */

int main(void)
{
	FILE *f = NULL;

	if(!(f = fopen("TEST.RAW", "wb")))
		perror("fopen");
	else
	{
		const double maxAngle = M_PI * 2;

		double angle;

		unsigned char cImage[HEIGHT][WIDTH];

		memset(&cImage, BKGRND, sizeof(cImage));

                /* Draw circle */
		for(angle = 0.0; angle < maxAngle; angle += 0.01)
		{
			const int y = (RADIUS * sin(angle)) + CENTRE,
				  x = (RADIUS * cos(angle)) + CENTRE;

			cImage[y][x] = FRGRND;
		}

		/* Dump array to disk.. */
		if(fwrite(cImage, sizeof(unsigned char), WIDTH * HEIGHT, f) != WIDTH * HEIGHT)
			perror("fwrite");

		fclose(f);
	}

	puts("Press Enter to exit..");
	getchar();

	return 0;
}

attachicon.gifrawcircle.png

Υ.Γ.

Το πρόγραμμα έχει δοκιμασθεί σε C++ Builder και μπορεί να περιέχει bugs ή άλλες αβλεψίες..

 

Ωραίος φίλε , θα του κάνω 2 αλλαγές για να το φέρω στα μέτρα μου... ( να γεμίζει τον κύκλο με χρώμα και να μπορώ να του δώσω εγώ την ακτίνα..  :-D  Thnx Directx

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

 

Μια μικρή υλοποίηση του πρώτου τρόπου (μου είναι πιο οικείος) σε C..

 

 

// Draw circle to RAW file
#include <stdio.h>
#include <string.h>
#include <math.h>

#define WIDTH  	256
#define HEIGHT  256
#define CENTRE 	128
#define RADIUS	100
#define BKGRND	225	/* background */
#define	FRGRND	 65	/* foreground */

int main(void)
{
	FILE *f = NULL;

	if(!(f = fopen("TEST.RAW", "wb")))
		perror("fopen");
	else
	{
		const double maxAngle = M_PI * 2;

		double angle;

		unsigned char cImage[HEIGHT][WIDTH];

		memset(&cImage, BKGRND, sizeof(cImage));

                /* Draw circle */
		for(angle = 0.0; angle < maxAngle; angle += 0.01)
		{
			const int y = (RADIUS * sin(angle)) + CENTRE,
				  x = (RADIUS * cos(angle)) + CENTRE;

			cImage[y][x] = FRGRND;
		}

		/* Dump array to disk.. */
		if(fwrite(cImage, sizeof(unsigned char), WIDTH * HEIGHT, f) != WIDTH * HEIGHT)
			perror("fwrite");

		fclose(f);
	}

	puts("Press Enter to exit..");
	getchar();

	return 0;
}

attachicon.gifrawcircle.png

Υ.Γ.

Το πρόγραμμα έχει δοκιμασθεί σε C++ Builder και μπορεί να περιέχει bugs ή άλλες αβλεψίες..

 

Μπράβο φίλε μου που ασχολήθηκες, αλλά όλα στη main; Πολύ κακή προγραμματιστική συνήθεια ακόμα και για το πιο απλό πρόγραμμα!

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Μπράβο φίλε μου που ασχολήθηκες, αλλά όλα στη main; Πολύ κακή προγραμματιστική συνήθεια ακόμα και για το πιο απλό πρόγραμμα!

Όταν πρόκειται για κάτι τόσο απλό επέτρεψε μου να διαφωνήσω μαζί σου.
  • Like 2

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Όταν πρόκειται για κάτι τόσο απλό επέτρεψε μου να διαφωνήσω μαζί σου.

Επίτρεψέ μου να διαφωνήσω και εγώ. Αξίζει να κάνεις ακόμα και μια σειρά κώδικα συνάρτηση, αν αυτό κάνει πιο ευανάγνωστο τον κώδικά σου. ;)

 

Τέτοια και άλλα αντίστοιχα θέματα πραγματεύεται το εξαιρετικό βιβλίο Refactoring του Fowler. Θα σου αλλάξει τον τρόπο που προγραμματίζεις! Στόχος -μεταξύ άλλων- είναι τα προγράμματα να είναι τόσο ευανάγνωστα που να μη χρειάζονται comments!

 

Φιλικά πάντα!

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

 

Μια μικρή υλοποίηση του πρώτου τρόπου (μου είναι πιο οικείος) σε C..

 

 

// Draw circle to RAW file
#include <stdio.h>
#include <string.h>
#include <math.h>

#define WIDTH  	256
#define HEIGHT  256
#define CENTRE 	128
#define RADIUS	100
#define BKGRND	225	/* background */
#define	FRGRND	 65	/* foreground */

int main(void)
{
	FILE *f = NULL;

	if(!(f = fopen("TEST.RAW", "wb")))
		perror("fopen");
	else
	{
		const double maxAngle = M_PI * 2;

		double angle;

		unsigned char cImage[HEIGHT][WIDTH];

		memset(&cImage, BKGRND, sizeof(cImage));

                /* Draw circle */
		for(angle = 0.0; angle < maxAngle; angle += 0.01)
		{
			const int y = (RADIUS * sin(angle)) + CENTRE,
				  x = (RADIUS * cos(angle)) + CENTRE;

			cImage[y][x] = FRGRND;
		}

		/* Dump array to disk.. */
		if(fwrite(cImage, sizeof(unsigned char), WIDTH * HEIGHT, f) != WIDTH * HEIGHT)
			perror("fwrite");

		fclose(f);
	}

	puts("Press Enter to exit..");
	getchar();

	return 0;
}

attachicon.gifrawcircle.png

Υ.Γ.

Το πρόγραμμα έχει δοκιμασθεί σε C++ Builder και μπορεί να περιέχει bugs ή άλλες αβλεψίες..

 

 

Μπορείς να το κάνεις και πιο γρήγορο αν  εκμεταλλευτεις τη συμμετρία του κύκλου.

 

Για παράδειγμα μπορείς να πάρεις  τα x,y από το πρώτο ογδοημόριο και να βρεις τα υπόλοιπα :

 

(x, -y) , (-x,y) , (y , x) , ( -x , -y ) , ( -y,-x ) , (-y, x) , ( y,-x)

  • Like 2

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Επίτρεψέ μου να διαφωνήσω και εγώ. Αξίζει να κάνεις ακόμα και μια σειρά κώδικα συνάρτηση, αν αυτό κάνει πιο ευανάγνωστο τον κώδικά σου. ;)

Και πάλι διαφωνώ, σεβόμενος όμως την άποψη σου, μάλιστα δεν θα ήταν άσχημο να αναρτήσεις μια εκδοχή του προγράμματος κατ' όπως κρίνεις εσύ καλύτερα.

 

Καλή συνέχεια!!

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Προφανώς δεν θα κατάλαβα καλά αλλά ο κώδικας που θέλεις να κάνει ο DirectX refactor σε συναρτήσεις είναι ο κώδικας των 49 γραμμών (με 3 γραμμές σχολίων και 12 κενές) του spoiler ?

 

Αν ναι, συμφωνώ και εγώ μαζί του εκτός αν το refactor είναι στο πλαίσιο της πρωταπριλιάς :)

  • Like 1

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

To να γράψεις ένα πρόγραμμα που να καταλαβαίνει ο υπολογιστής είναι εύκολο, το θέμα είναι να το γράψεις έτσι ώστε να το καταλαβαίνουν εύκολα οι άνθρωποι! Μπορεί να κάτσω κάποια στιγμή να το κάνω refactor αν θέλετε πάντως! Είναι καλή συνήθεια.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

To να γράψεις ένα πρόγραμμα που να καταλαβαίνει ο υπολογιστής είναι εύκολο, το θέμα είναι να το γράψεις έτσι ώστε να το καταλαβαίνουν εύκολα οι άνθρωποι! Μπορεί να κάτσω κάποια στιγμή να το κάνω refactor αν θέλετε πάντως! Είναι καλή συνήθεια.

 

Ορίστε, το έκανα εγώ refactor, και με σχόλια και με sanity checks και με intrusive auto-fixes, και με reusability, κλπ...

 

 

 

/* Header inclusions */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/* Constants & Macros */

#define PI		3.14159265358979323846
#define MIN(x,y)	( (x) < (y) ? (x) : (y) )

#define IMG_FNAME	"_circle.raw"
#define IMG_H		256		/* image height */
#define IMG_W		256		/* image width */

#define BG_COLOR	225
#define FG_COLOR	65

#define C_CENTER	128
#define C_RADIUS	100

/* Custom Types */

typedef unsigned char Byte;

typedef struct RawImage {
	int w, h;
	Byte *buffer;
}RawImage;

/* Function Prototypes */

static int rawImage_is_valid( RawImage *image );
static int rawImage_init( RawImage *image, int height, int width, Byte bgcolor );
static int rawImage_cleanup( RawImage *image );
static void rawImage_draw_circle( RawImage *image, int center, int radius, Byte fgColor );
static int rawImage_save( RawImage *image, char *fname );

/* Function Definitions */

/* -------------------------------------------------
 * program's entry point
 */
int main( void )
{
	RawImage image = {0,0, NULL};
	int ret = 0;

	if ( !rawImage_init( &image, IMG_H, IMG_W, BG_COLOR) ) {
		fputs( "*** fatal error, aborting...\n", stderr );
		ret = 1;
	}
	else {
		rawImage_draw_circle( &image, C_CENTER, C_RADIUS, FG_COLOR );
		rawImage_save( &image, IMG_FNAME);
		rawImage_cleanup( &image );
	}

	system( "pause" );	/* Windows only */
	return ret;
}

/* ------------------------------------------------- */
static int rawImage_is_valid( RawImage *image )
{
	return 	image
		&& image->buffer
		&& image->h > 0
		&& image->w > 0
		;
}

/* -------------------------------------------------
 * init an (already existed) image according to the specified specidications
 */
static int rawImage_init( RawImage *image, int height, int width, Byte bgcolor )
{
	int i;
	const int npixels = height * width;

	/* sanity check */
	if ( !image ) {
		fputs( "rawImage_init: invalid pointer argument\n", stderr );
		return 0;
	}

	/* demand valid dimensions */
	if ( height < 1 || width < 1 ) {
		fputs( "rawImage_init: invalid image dimensions\n", stderr );
		return 0;
	}

	/* apply specifications */

	if ( image->buffer ) {
		puts( "rawImage_init: overwriting old data" );
		free( image->buffer );
	}

	image->buffer = calloc(npixels, sizeof(Byte) );
	if ( NULL == image->buffer ) {
		perror( "rawImage_init: calloc" );
		return 0;
	}

	for (i=0; i < npixels; i++)
		image->buffer[i] = bgcolor;
	image->h = height;
	image->w = width;

	return 1;
}

/* ------------------------------------------------- */
static int rawImage_cleanup( RawImage *image )
{
	if ( !image ) {
		fputs( "rawImage_init: invalid pointer argument\n", stderr );
		return 0;
	}

	image->h = 0;
	image->w = 0;
	if ( image->buffer ) {
		free( image->buffer );
		image->buffer = NULL;
	}

	return 1;
}

/* ------------------------------------------------- */
static void rawImage_draw_circle( RawImage *image, int center, int radius, Byte fgColor )
{
	double angle;
	const double maxANGLE = 2 * PI;

	/* ensure valid rawImage */
	if ( !rawImage_is_valid(image) ) {
		fputs( "rawImage_draw_circle: invalid image\n", stderr );
		return;
	}

	/* ensure proper radius */
	if ( radius < 0 ) {
		radius = abs(radius);
		puts( "*** rawImage_draw_circle: negative radius fixed" );
	}
	else if ( 0 == radius ) {
		radius = 1;
		puts( "*** rawImage_draw_circle: 0 radius fixed to 1" );
	}
	/* ensure proper center + radius */
	int maxrange = MIN(image->h, image->w);
	if ( center + radius > maxrange ) {
		puts( "*** rawImage_draw_circle: circle scaled down to fit the image" );
		center = radius = maxrange / 2;
	}

	/* draw the circle */
	for (angle = 0.0; angle < maxANGLE; angle += 0.01)
	{
		int y = (radius * sin(angle)) + center;
		int x = (radius * cos(angle)) + center;

		image->buffer[y * image->w + x] = fgColor;
	}
}

/* -------------------------------------------------
 * save the buffer of an image to disk
 */
static int rawImage_save( RawImage *image, char *fname )
{
	FILE *fp = NULL;
	int ret = 1;

	if ( !rawImage_is_valid(image) ) {
		fputs( "rawImage_save: invalid image\n", stderr );
		return 0;
	}

	/* save buffer of image to disk */
	size_t buflen = image->h * image->w;
	if ( NULL == (fp = fopen(fname, "wb")) ) {
		perror("rawImage_save: fopen");
		return 0;
	}
	if ( buflen != fwrite(image->buffer, sizeof(Byte), buflen, fp) ) {
		perror("rawImage_save: fwrite");
		ret = 0;
	}
	 
	fclose(fp);

	return ret;
}

 

 

Η αρχική έκδοση του DirectX εξακολουθεί να είναι μακράν πιο ευανάγνωστη.

 

Όπως είπαν και τα άλλα παιδιά, για τόσο μικρό κώδικα που έτσι κι αλλιώς παρατέθηκε ως απλό παράδειγμα το "production refactoring" περισσότερο δυσχεραίνει παρά διευκολύνει την ανάγνωση της ουσίας, γιατί κουβαλάει ένα κάρο visual (και όχι μόνο) overhead μαζί του.

  • Like 3

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε έναν λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι εύκολο!

Εγγραφείτε για έναν νέο λογαριασμό

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
×
×
  • Δημιουργία νέου...

Χρήσιμες πληροφορίες

Με την περιήγησή σας στο insomnia.gr, αποδέχεστε τη χρήση cookies που ενισχύουν σημαντικά την εμπειρία χρήσης.