rekensom in C

trix

Golden Member

ik zit met een eenvoudig probleempje,......altans niet voor mij ;)

ik wil in een byte weten of de 7e bit "0" is, dat doe je toch door er een masker over te leggen ?
maar ik weet niet hoe.

eigenwijs = ook wijs

if ((byte & 0x80) == 0) {

...
}
bit 7 is bij mij natuurlijk het hoogste bit!

[Bericht gewijzigd door henri62 op zondag 31 januari 2021 11:54:25 (77%)

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
trix

Golden Member

_/-\o_

[Bericht gewijzigd door trix op zondag 31 januari 2021 11:56:08 (95%)

eigenwijs = ook wijs

Het 7e bit is ook het negatief bit in een signed integer, hoef je er geen masker op te zetten.

Op 31 januari 2021 11:53:26 schreef rwk:
Het 7e bit is ook het negatief bit in een signed integer, hoef je er geen masker op te zetten.

Maakt het alleen wel onleesbaar want je moet waarschijnlijk met casts gaan klooien etc.

Maar om even terug te komen op het grotere "plaatje". Ik zou het compleet anders aanpakken.

Het hele detectie algorithme in een microcontroller stoppen is eigenlijk een behoorlijke klus en weggegooide tijd.

Wat ik zou doen is zorgen dat je een betrouwbaar plaatje met je scanner maakt, dat stuur je naar een PC en daar analyseer je het beeld met moderne tools zoals octave of opencv etc. Die tools zijn enorm krachtig en daar kun je niet tegen werken.

Dan bepaal je wat je verder moet doen en stuur je je machine aan die het "low level" werk doet. Daar is een microcontroller natuurlijk weer wel goed in.

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
trix

Golden Member

dan komt er een PC bij, wil het juist simpel houden. voor als nog is daar geen reden toe.

alles goed ?
ik zal wel laten weten wanneer er voldoende werkt om een kijkje te nemen.
mag altijd komen kijken natuurlijk.

[Bericht gewijzigd door trix op zondag 31 januari 2021 11:56:34 (43%)

eigenwijs = ook wijs

Op 31 januari 2021 11:55:57 schreef trix:
alles goed ?

Ja alles goed met me, alleen veel te druk met allerlei projecten en dus de eeste 2 maanden "vol" met ander werk.

ik zal wel laten weten wanneer er voldoende werkt om een kijkje te nemen.
mag altijd komen kijken natuurlijk.

dan komt er een PC bij, wil het juist simpel houden. voor als nog is daar geen reden toe.

Misschien is dit nu wel de reden om dat te doen?
Het probleem is dat dit soort detectie algorithmes behoorlijk complex zijn. En daar bedoel ik mee dat als je een klein beetje scheve lijnen hebt, ruis in je plaatje en dat soort onvolkomenheden hebt het snel uit de hand loopt.

Dat allemaal in C maken is veel werk, op een PC met een scripting language is zoiets heel snel te maken (zelf geen echte practische ervaring).
Bijvoorbeed een edge detectie met OpenCV aangestuurd in python:
https://www.geeksforgeeks.org/python-detect-corner-of-an-image-using-o…

Dan heb je natuurlijk alleen de hoekpunten (en het zijn dunne lijnen, bij jouw zijn het "balken"), daarna moet je alsnog de binnen en buitenkant bepalen voor jouw doel. Ook een klusje wat lastig is.

Al gebruik je de PC maar om je proof-of-concept (POC) uit te testen of het echt ook gaat werken.
Wil je het later volledig stand-alone maken kun je alsnog het moeilijke pad bewandelen en alles in een microcontroller proberen te stoppen.

Maar zelfs dat laatste pad is onnodig: Je kunt ook micro PC's kopen in een kastje zo groot als een kleine broodtrommel, die koppel je dan aan de besturing die het real time werk doet.

-edit- Ik ben zelf geen fan van python, maar OpenCV is een C++ library die je later ook los kunt gebruiken. Na de POC gooi je python eruit en maak je het in C++.
Ik zeg ook altijd je moet problemen oplossen in de taal die daar het meest geschikt voor is.

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
trix

Golden Member

voor als nog denk ik dat ik het gewoon werkend krijg met de controller, de uitkomst van die coordinaten mag gerust 1 of 2 pixels afwijken van de werkelijkheid, dat is niet zo'n probleem.
als het werkstuk dus een beetje scheef hangt b.v. maakt dat niet uit.
de scanner levert ook voor zover ik het kan zien strakke resultaten, dus ook weinig "ruis" uit die hoek.

de buitenste hoeken kan ik nu vinden, ik ben nu bezig met de binnenste.
hier ga ik met een lijn (1 rij pixels) kijken binnen de eerder gevonden buiten hoeken, de over gangen licht & donker ("1" & "0") geven dan een hor. of vert. lijn aan. de snijpunten zijn dan de hoeken.

ik zal eens een stukje code posten die de groen omkaderde lijn zoekt. recht toe recht aan geprogrameerd. om een idee van mijn aanpak te geven. (95% klaar)

c code:


// *****************************************************************************************************
// *** WE GONNA SEARCH THE INNER CORNER ****************************************************************
// *** FIRST WE SEARCH FOR AL THE Y-odd LINES **********************************************************
// *****************************************************************************************************

for (Y_scan = 0; Y_scan < 15000; Y_scan = Y_scan + 1000) // from top to bottem
{                                                        // temporarily 15000, because we don't want to
													  	 // search in random area
														   														   
	for (X_scan = (X1_line + 15); X_scan < (X1_line + 16); X_scan ++) // from left to right, we make the X-axle smaller
	{				                                                  // were in whe look from top to bottem
		
		RAM_address = Y_scan + X_scan; // is address in the ext. RAM
		cb_1 = ram_read (RAM_address); // functie
		
		// *** WE GONNA SEARCH FOR THE Y1 line *****************************************************************
		
		if (cb_1 != 0) // if cb_1 = ongelijk aan 0
		{				
			cb_2 = ram_read (RAM_address - 1000); // functie     previous byte above cb_1
			cb_3 = ram_read (RAM_address + 1000); // functie     next byte below cb_1
			
			if (cb_1 == 0b10000000)
			{				 
				if ((cb_2 == 0b00000111) || (cb_2 == 0b00001111) || (cb_2 == 0b00011111) ||
					(cb_2 == 0b00111111) || (cb_2 == 0b01111111) || (cb_2 == 0b11111111))
				{ match_1 = 1;}
			}
			
			if (cb_1 == 0b11000000)
			{ 				
				if ((cb_2 == 0b00000011) || (cb_2 == 0b00000111) || (cb_2 == 0b00001111) ||
					(cb_2 == 0b00011111) || (cb_2 == 0b00111111) || (cb_2 == 0b01111111) ||
					(cb_2 == 0b11111111))
				{ match_2 = 1; }
			}
			
			if (cb_1 == 0b11100000)
			{				
				if ((cb_2 == 0b00000001) || (cb_2 == 0b00000011) || (cb_2 == 0b00000111) ||
				(cb_2 == 0b00001111) || (cb_2 == 0b00011111) || (cb_2 == 0b00111111) ||
				(cb_2 == 0b01111111) || (cb_2 == 0b11111111))
				{ match_3 = 1;  }
			}
			
			if (match_1 == 1) { R = (((Y_scan/1000) + 1) * 8) - 8; Y_line_I_found = 1; PORTF |= (1 << PINF7);}
			if (match_2 == 1) { R = (((Y_scan/1000) + 1) * 8) - 7; Y_line_I_found = 1; PORTF |= (1 << PINF6);}			 
			if (match_3 == 1) { R = (((Y_scan/1000) + 1) * 8) - 6; Y_line_I_found = 1; PORTF |= (1 << PINF5);}			
			
				
			// below: if 4 neighbors bits in the same byte are "1",	
				
			if (cb_1 == 0b11110000) { R = (((Y_scan/1000) + 1) * 8) - 5; Y_line_I_found = 1; PORTF |= (1 << PINF4);}
			if (cb_1 == 0b01111000) { R = (((Y_scan/1000) + 1) * 8) - 4; Y_line_I_found = 1; PORTF |= (1 << PINF3);}	
			if (cb_1 == 0b00111100) { R = (((Y_scan/1000) + 1) * 8) - 3; Y_line_I_found = 1; PORTF |= (1 << PINF2);}	
			if (cb_1 == 0b00011110) { R = (((Y_scan/1000) + 1) * 8) - 2; Y_line_I_found = 1; }	
				
			if ((cb_1 == 0b00001111) && (cb_3 == 0b00000000)) { R = (((Y_scan/1000) + 1) * 8) - 0; Y_line_I_found = 1; }	
			if ((cb_1 == 0b00000111) && (cb_3 == 0b10000000)) { R = (((Y_scan/1000) + 2) * 8) - 8; Y_line_I_found = 1; }
			if ((cb_1 == 0b00000011) && (cb_3 == 0b11000000)) { R = (((Y_scan/1000) + 2) * 8) - 7; Y_line_I_found = 1; }	
			if ((cb_1 == 0b00000001) && (cb_3 == 0b11100000)) { R = (((Y_scan/1000) + 2) * 8) - 6; Y_line_I_found = 1; }
				
			if (cb_1 == 0b11111000) { R = (((Y_scan/1000) + 1) * 8) - 4; Y_line_I_found = 1; PORTF |= (1 << PINF0);}			
			if (cb_1 == 0b11111100) { R = (((Y_scan/1000) + 1) * 8) - 3; Y_line_I_found = 1; }
			if (cb_1 == 0b11111110) { R = (((Y_scan/1000) + 1) * 8) - 2; Y_line_I_found = 1; }								
			if (cb_1 == 0b11111111) { R = (((Y_scan/1000) + 1) * 8) - 1; Y_line_I_found = 1; PORTF |= (1 << PINF1);}
				
			if ((Y_line_I_found == 1) && (Y_line_I_found_temp == 1))
			{				
				Y_line_I_found = 0;
				Y_line_I_found_temp = Y_line_I_found_temp + 1;
				
				Y1_line_I = R;				
			}			
			 
			
			if ((Y_line_I_found == 1) && (Y_line_I_found_temp == 2))
			{				
				Y_line_I_found = 0;
				Y_line_I_found_temp = Y_line_I_found_temp + 1;
				
				Y3_line_I = R;
			}			
			
//			if (Y_line_I_found_temp == 2) // we can jump out of the loop
//			{
//				X_scan = X1_line + 16;
//				Y_scan = 36000;
//			}		
		 
		} // from: if (cb_1 != 0)
	} // from: (for (X_scan..............
//	NM = 0; // new matrix 
} // from: (for (Y_scan..............
eigenwijs = ook wijs
Frederick E. Terman

Honourable Member

Ik zou gewoon zelf ook (eenmalig!) een serie plaatjes maken; beetje groter en kleiner, beetje verschoven..., en die XOR'ren met het gescande plaatje. Daarvoor hoef ik de bytes niet uit elkaar te halen; gewoon XOR op de hele bytes.
Zolang het nergens op lijkt zal de gemiddelde match over het plaatje zo'n beetje halverwege ruisen.
Maar als één of enkele van mijn plaatjes een hoge match opleveren heb ik blijkbaar het gezochte figuurtje te pakken. Of juist een heel lage match, dan staat het in negatief.

Keramisch, kalibratie, parasitair: woordenlijst.org
Hoeben

Golden Member

Op 31 januari 2021 12:03:52 schreef henri62:
-edit- Ik ben zelf geen fan van python, maar OpenCV is een C++ library die je later ook los kunt gebruiken. Na de POC gooi je python eruit en maak je het in C++.
Ik zeg ook altijd je moet problemen oplossen in de taal die daar het meest geschikt voor is.

Python is juist voor dit soort kleinere taken heel geschikt. Met C++ ben je meteen een groots iets aan het bouwen, met veel lagen software die alleen maar data aan elkaar doorgeven. Wel mooi en structuur, maar dat is niet altijd nodig.

Overigens gebruik ik als ik iets snel nodig heb Delphi / RX RAD studio. Userinterface in 5 minuten gemaakt en hij "eet" naast Pascal ook C++.

Arco

Special Member

Ik zou gewoon zelf ook (eenmalig!) een serie plaatjes maken; beetje groter en kleiner, beetje verschoven...

Lang geleden heb ik al voorgesteld een camera met object recognition te gebruiken... (da's toch wel iets simpeler qua hardware... ;) )

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
trix

Golden Member

Op 31 januari 2021 14:07:54 schreef Frederick E. Terman:
Ik zou gewoon zelf ook (eenmalig!) een serie plaatjes maken

dat gaat niet de diversiteit is daar voor te groot.

ik denk dat b.v. dat openCV wel gaat werken natuurlijk, (al kan het veel & veel meer dat ik nodig heb) en ik houd dat zeker nog in gedachten.
maar voordeel bij mij is dat het niet super nauwkeurig hoeft te zijn een afwijking van 1 of 2 pixels (10 of 20 mm) is geen probleem.
dan is die "jan-boeren-fluitjes" methode van mij gewoon voldoende, goed = goed.

eigenwijs = ook wijs
Arco

Special Member

Je moet er dan ook rekening mee houden dat er hier en daar wat 'spikkels' in de vierkanten kunnen zitten die je moet negeren...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
trix

Golden Member

vandaar dat ik bij een "match" ( een "1" gevonden) meteen controleer of de buurmannen ook "1" zijn, zo niet, negeren.

eigenwijs = ook wijs
Hoeben

Golden Member

Op 31 januari 2021 17:25:06 schreef Arco:
Je moet er dan ook rekening mee houden dat er hier en daar wat 'spikkels' in de vierkanten kunnen zitten die je moet negeren...

Of je gebruikt mijn least-squares curve fit. Wat dat eigenlijk doet is de pixels die meer in het gemiddelde zitten zwaarder meetellen waardoor de extremen/afwijkingen minder meetellen.

Maar de camera van Arco is waarschijnlijk de beste oplossing. Die camera doet pattern matching, ook een fitting van een plaatje in plaats van lijnen.

trix

Golden Member

ik ben nog het een en ander aan het testen, en nu vroeg ik mij af of er een functie/methode bestaat om te bepalen of een getal even of oneven is ?

tnx.

eigenwijs = ook wijs

Bitje nummer 0 testen, zelfde truuk als het bitje 7 wat ik al aangaf. Is het bitje 0 = even.

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.

code:


Bool even (int a)
{
  return ! (a&1);
}
Bool odd (int a)
{
  return  (a&1);
}
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
trix

Golden Member

ach,....natuurlijk, zo simpel kan het zijn bedankt _/-\o_

dat met de bool moet ik nog eens bekijken.

[Bericht gewijzigd door trix op zondag 14 februari 2021 10:39:00 (28%)

eigenwijs = ook wijs

Sommige mensen vinden het "leuk" om onderscheid te maken tussen een logische waarde (ja/nee) en een "int". De taal C maakt dat onderscheid niet echt. 0 is gewoon "nee / FALSE" en alle andere waardes, maar liefst "1" is gewoon "ja / TRUE".

Als je het onderscheid wil maken, zet JIJ bovenaan ergens:

#define Bool int

en de compiler merkt het verschil niet, maar in de code maak je dan aan de menselijke lezer duidelijk door "Bool" te schrijven dat hier een int als ja/nee variabele wordt gebruikt.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
trix

Golden Member

eigenwijs = ook wijs

Op 14 februari 2021 10:57:34 schreef rew:

Als je het onderscheid wil maken, zet JIJ bovenaan ergens:

#define Bool int

Getver! Niet doen, stoppen met het maken van eigen types voor bools en bytes en die meuk.
Ik heb daar al zoveel ellende mee gezien.

Die het op de manier zoals het hoort (nagenoeg alle compilers ondersteunen dat):

code:


#include <stdint.h>
#include <stdbool.h>

Dan gewoon 'bool' in je programma gebruiken.

Voor bytes (unsigned) gebruik je de uint8_t. Voor 16 bits uint16_t enzovoort.

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.

Ik doe dat toch nooit, dus ik weet niet hoe het moet. :-)

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
trix

Golden Member

nog een rekensom in C, dus in het zelfde topic,

ik heb een rij van bytes achter elkaar. en ik heb een nummer van een bit,
b.v. bit 23.
nu wil ik graag weten in welke byte dat bit zit (3e byte natuurlijk).

hoe reken ik dat het best uit ?
tnx.

eigenwijs = ook wijs

dat is op pagina 1 al beantwoord?

Op 29 januari 2021 10:52:58 schreef DK:
Delen (int) door 8?
12/8=1
18/8=2
25/8=3e byte
Modulo functie weet je welk bit ook nog

Normaal begin je bij byte 0 met tellen

GMT+1