Python, process Killed, kartor med bilder och marker

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Python, process Killed, kartor med bilder och marker

Inlägg av Oltronix »

Jag har meckat med bilder som jag tagit och lagt upp på karta med markörer. Markörerna är klickbara och då poppar bild upp. Det är intressant hur man kan se onogrannheten hos GPS i moblierna. När man vet att flera bilder tagit på samma ställe men det ligger på olika ställen på kartan. Jag har använt Iphone4 och SamsungS8.

1.När jag läser metadata med ett program för att plocka ut kordnaterna, om det finns några i metadatan, så dör processen med infon "Killed" efter många minuter. Inte mycket info. Dock hinnar jag få en hyffsat stor file som jag kan labba vidare med i nästa steg att bygga karta. Och jag vet inte hur jag skall felsöka för att bli av med "Killed". Det är c.a 18000 bilder. Jag kan förståss pröva att analysera färre bilder men jag är nyfiken och vill analysera och lära nytt.

När jag kör processen, och den snurrar , ser det ut så här:

Kod: Markera allt

erik@HP:~/Bilder/ASUS$ free -m
              total        used        free      shared  buff/cache   available
Mem:           7868        3742          99         314        4026        3565
Swap:          2047        1545         502
När processen inte är igång:

Kod: Markera allt

erik@HP:~/Bilder/ASUS$ free -m
              total        used        free      shared  buff/cache   available
Mem:           7868        3481        3983         194         403        3956
Swap:          2047        2004          43
Det bara en hypotes jag har att det är något med att resurserna tar slut i datorn.

2. Jag måste krympa bilderna för lägga upp 100tals bilder på 4-5MB blir en jätte html-file som inte min browser klarar av att hantera. Html-filen är underlag för kartan. Men de okrympa bilderna måste jag använda för att hämta metadata. Metadata försvinner från de krympta bilderna. Så det jag gör är att krympa bilderna med ett bash-script som lägger dem i en mapp som heter "krymp3".

Så här ser en enskild post ut:

Kod: Markera allt

/home/erik/Bilder/ASUS/Bilder/2019/Samsung_S8/20181021_171115.jpg
59.31805555555556 18.06388888888889
Jag vill lägga in "krymp3" framför det egentliga filnamnet. Hitills har jag gjort det manuellt med en editor.

Kod: Markera allt

/home/erik/Bilder/ASUS/Bilder/2019/Samsung_S8/krymp3/20181021_171115.jpg
59.31805555555556 18.06388888888889
Jag kan förståss läsa strängen baklänges och leta efter första "/".
Annan ide?

Dator: ubuntu 18.4.04
erik@HP$ uname -a
Linux HP 5.3.0-62-generic #56~18.04.1-Ubuntu SMP Wed Jun 24 16:17:03 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Python 3.6.9
Leaflet 1.6.0

from exif import Image: (Image för att läsa metadata)
import folium: (foiium för att skapa kartan)
guckrum
Inlägg: 1691
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Python, process Killed, kartor med bilder och marker

Inlägg av guckrum »

Om du bara processar en bild i taget skall du ju inte få "out of memory"

Vilket felmeddelande får du?

Krymp bilder i Python med PIL.

Använd os.path för att hantera filnamn och paths.
Maalobs
Inlägg: 1299
Blev medlem: 3 februari 2005, 14:35:15
Ort: Stockholm

Re: Python, process Killed, kartor med bilder och marker

Inlägg av Maalobs »

Jag kan inte Python, men här är ett Perl-script som fixar det jag tolkar att du vill göra.

Kör det här joxet först för att hämta Image::ExifTool modulen till Perl, samt ImageMagick-programmen:

Kod: Markera allt

sudo apt-get update
sudo apt-get install libimage-exiftool-perl
sudo apt-get install imagemagick-6.q16
Här är en länk till dokumentationen för den metod som används från Image::ExifTool:
https://exiftool.org/ExifTool.html#SetNewValuesFromFile
Du kan se där i exemplen att jag använder den metod som kopierar alla taggar as-is.
Det finns även ett exempel där som bara berör gps-taggar, om det är vad du föredrar.
Jag har lagt till det som en bortkommenterad rad i koden så du kan testa det om du vill.

Som referens, här är även en länk till dokumentationen för mogrify från ImageMagick:
https://imagemagick.org/script/mogrify.php

Ange vilka storleksparametrar du vill ha på de krympta filerna genom att sätta önskade värden på $pixelwidth och $pixelheight i scriptet.

En sammanfattning av vad scriptet gör:
1. Hitta varje *.jpg och *.jpeg i källmappen $srcdir.
2. Kopiera den första funna filen till målmappen $destdir.
3. Skala ner den kopierade målfilen till önskad storlek.
4. Läs av alla taggar från källfilen och skriv in dem på målfilen.
5. Behandla nästa fil i källmappen.

Att behandla alla filer en efter en istället för att kopiera allihopa först och sedan behandla dem, innebär att du inte behöver ha diskutrymme för samtidig dubbel uppsättning av alla stora filer.

Kod: Markera allt

#!/usr/bin/perl

use strict;
use warnings;
use File::Path;
use File::Copy;
use Image::ExifTool qw(:Public);

# These must have / at the end.
my $srcdir = '/home/erik/Bilder/ASUS/Bilder/2019/Samsung_S8/';
my $destdir = '/home/erik/Bilder/ASUS/Bilder/2019/Samsung_S8/krymp3/';

# Size of destination files.
my $pixelwidth = 640;
my $pixelheight = 480;

# Create destdir if it doesn't exist.
mkpath ($destdir, {verbose => 1, mode => 0744}) unless (-e $destdir);

my $exifTool = new Image::ExifTool;

my $file;
opendir my $dh, $srcdir or die "Can't opendir '$srcdir': $!\n";
while (defined($file = readdir $dh)) {
	next unless (-f $srcdir . $file);		# Only process files.
	next unless ($file =~ m!\.jpe?g$!i);	# Filename must end with ".jpg" or ".jpeg", case insensitive.

	print "Processing: '$srcdir$file' - ";

	if (-e $destdir . $file) {
		print "'$destdir$file' already exists, skipped.\n";
		next;
	}

	if (copy $srcdir . $file, $destdir . $file) {
		# File copy was successful, run mogrify to downscale the image size on the copy.
		system('mogrify -resize ' . $pixelwidth . 'x' . $pixelheight . ' ' . $destdir . $file) and die "Failed to execute 'mogrify': $!\n";
	} else {
		die "Failed to copy '$srcdir$file' to '$destdir$file': $!\n";
	}

	# Set new values from all information in a file...
	$exifTool->SetNewValuesFromFile($srcdir . $file, '*:*<EXIF:*');
	
	# Alternative to above; Only copy GPS-tags:
	#$exifTool->SetNewValuesFromFile($srcdir . $file, 'gps*');
	
	# ...then write these values to another image
	my $result = $exifTool->WriteInfo($srcdir . $file, $destdir . $file);

	if ($result) {
		print "Failed\n";
	} else {
		print "Success\n";
	}
}
Med kommandot exiftool kan du efteråt dumpa alla taggar i en bildfil för att bekräfta att dina önskade taggar har kopierats över:

Kod: Markera allt

exiftool /home/erik/Bilder/ASUS/Bilder/2019/Samsung_S8/krymp3/20181021_171115.jpg
Senast redigerad av Maalobs 8 juli 2020, 11:11:09, redigerad totalt 2 gånger.
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: Python, process Killed, kartor med bilder och marker

Inlägg av Oltronix »

guckrum skrev:Om du bara processar en bild i taget skall du ju inte få "out of memory"

Vilket felmeddelande får du?

Krymp bilder i Python med PIL.

Använd os.path för att hantera filnamn och paths.
-Jag hanterar en fil i taget. Det felmeddelande jag får är endast "Killed". Inget mer.
-Ja kollade efter att krympa filer i Python men hittade inget vettigt. Skall kolla PIL.
-Inte använt os.path. Jag kollar även där.

-Maalobs: Perl har jag inte använt tidigare. Jag får testa.
Maalobs
Inlägg: 1299
Blev medlem: 3 februari 2005, 14:35:15
Ort: Stockholm

Re: Python, process Killed, kartor med bilder och marker

Inlägg av Maalobs »

Du kan ju köra ImageMagicks mogrify från Python också, så här ser kommandoraden ut:

Kod: Markera allt

mogrify -resize 640x480 /home/erik/Bilder/ASUS/Bilder/2019/Samsung_S8/krymp3/20181021_171115.jpg
Här beskrivs det olika sätt att köra externa kommandon från Python:
https://stackoverflow.com/questions/892 ... rom-python

Du säger att du "hanterar en fil i taget", men har du först läst in alla filer i minnet samtidigt, innan du behandlar dem?
Det låter som att det är något sådant som händer om du får slut på minnet. :)
guckrum
Inlägg: 1691
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Python, process Killed, kartor med bilder och marker

Inlägg av guckrum »

Kan du visa kodsnutten ssom ger "killed"?
Bo.Siltberg
Inlägg: 363
Blev medlem: 30 juli 2018, 06:46:13

Re: Python, process Killed, kartor med bilder och marker

Inlägg av Bo.Siltberg »

Shellkommandot limit visar aktuella resursgränser om det är nåt sånt som spökar. Samma komman kan öka dem.
Lite printf-debugging bör kunna visa vad pythonprogrammet har för sig.
I värsta fall kan strace användas på processen.
guckrum
Inlägg: 1691
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Python, process Killed, kartor med bilder och marker

Inlägg av guckrum »

En jpeg-header är någon/några kilobyte i storlek och ligger tidigt i filen. Får man verkligen slut på minne av att läsa den är det något som är riktigt galet. Sannolikt är problemet ett annat.
Maalobs
Inlägg: 1299
Blev medlem: 3 februari 2005, 14:35:15
Ort: Stockholm

Re: Python, process Killed, kartor med bilder och marker

Inlägg av Maalobs »

Nu när jag testade så konstaterade jag att mogrify lämnar GPS-taggarna intakta efter resizing, så du behöver inte ens kopiera taggar:

Kod: Markera allt

$ exiftool image0.jpeg | egrep 'GPS|Size'
File Size                       : 2.5 MB
GPS Latitude Ref                : North
GPS Longitude Ref               : East
GPS Altitude Ref                : Above Sea Level
GPS Speed Ref                   : km/h
GPS Speed                       : 0
GPS Img Direction Ref           : True North
GPS Img Direction               : 194.4945525
GPS Dest Bearing Ref            : True North
GPS Dest Bearing                : 194.4945525
GPS Date Stamp                  : 2020:07:08
GPS Horizontal Positioning Error: 65 m
GPS Altitude                    : 23 m Above Sea Level
GPS Latitude                    : 59 deg 29' 44.74" N
GPS Longitude                   : 18 deg 3' 55.10" E
GPS Position                    : 59 deg 29' 44.74" N, 18 deg 3' 55.10" E
Image Size                      : 4032x3024
$ mogrify -resize 640x480 image0.jpeg
$ exiftool image0.jpeg | egrep 'GPS|Size'
File Size                       : 54 kB
GPS Latitude Ref                : North
GPS Longitude Ref               : East
GPS Altitude Ref                : Above Sea Level
GPS Speed Ref                   : km/h
GPS Speed                       : 0
GPS Img Direction Ref           : True North
GPS Img Direction               : 194.4945525
GPS Dest Bearing Ref            : True North
GPS Dest Bearing                : 194.4945525
GPS Date Stamp                  : 2020:07:08
GPS Horizontal Positioning Error: 65 m
GPS Altitude                    : 23 m Above Sea Level
GPS Latitude                    : 59 deg 29' 44.74" N
GPS Longitude                   : 18 deg 3' 55.10" E
GPS Position                    : 59 deg 29' 44.74" N, 18 deg 3' 55.10" E
Image Size                      : 640x480
Installera ImageMagick enligt tidigare instruktion, sedan kan du köra mogrify på dina filer i ett trivialt bash-script, eller om du kopierar allt till krymp3-mappen först så kan du köra mogrify -resize 640x480 *.jpg därinne efteråt.
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: Python, process Killed, kartor med bilder och marker

Inlägg av Oltronix »

guckrum skrev:Kan du visa kodsnutten ssom ger "killed"?

Kod: Markera allt

#2020-07-08
from exif import Image
import signal

path='/home/erik/Bilder/ASUS/Bilder/'
def Exit_program(signal, frame):
    print('--- CTRL C ---')
    sys.exit(0)

def conf_lat_long(lat, lon):
   lat= list(lat)  #convert tuple to list
   lon= list(lon)
   dlat = int(lat[0]) + (int(lat[1])/60.0) + (int(lat[2])/3600.0)
   dlon = int(lon[0]) + (int(lon[1])/60.0) + (int(lon[2])/3600.0)
   return dlat, dlon

def exif_test(file_jpg):
      try:
         with open(path+file_jpg, 'rb') as image_file:
            my_image = Image(image_file)
      except IsADirectoryError:
           pass
      except:
          pass
      try:
         lat=my_image.gps_latitude
         lon=my_image.gps_longitude
         print(path+file_jpg)   #file path to picture
         dlat, dlon = conf_lat_long(lat, lon) #decimal format of location
         print(dlat, dlon)    #location where picture taken
      except:
         #print("--- Image has No GPS data ---")
         pass
 
if __name__ == '__main__':
   signal.signal(signal.SIGINT, Exit_program)
   import time
   seconds = time.time()
   local_time = time.ctime(seconds)
   print("time:", local_time)		

   filepath = 'list_1'
   with open(filepath, 'r') as fp:
      line = fp.readline() #NB first file skipped
      while line: #NB empty lines will exit loop before EOF
         save_line=line
         line=fp.readline().rstrip()
         line=line.replace('./', '')
         exif_test(line)
   print('two last line read in:', filepath, save_line, line) #line if correct is an empty line
   seconds = time.time()
   local_time = time.ctime(seconds)
   print("time:", local_time)
Efter omboot får jag inga "Killed". Jag får låta bli att boota om varje dag. Jag får fortsätta med "Killed" problemet och de andra punkterna. Jag får tacka för input jag fått. Att sitta ensam utan att prata med någon skapar inte alltid bra ideer.

edit:
-Maalobs: Jag använder Netpbm för att krympa bilder. Jag skall pröva mogrify. Det kanske löser flera problem.
exiftool verkar superbra!
Maalobs
Inlägg: 1299
Blev medlem: 3 februari 2005, 14:35:15
Ort: Stockholm

Re: Python, process Killed, kartor med bilder och marker

Inlägg av Maalobs »

Ja, exiftool är ett Perl-script, i praktiken en frontend till den bakomliggande modulen (libraryt), men det är packeterat som ett standalone program, komplett med en perl tolk och ett wrapper-program som i bakgrunden packar upp paketet och kör det medföljande perl på det medföljande scriptet, som i sin tur JIT-kompilerar och exekverar resultatet.
Av den orsaken är det inte optimalt att köra exiftool i en loop i ett bash-script eller i en batfil, för det är en hög uppstartskostnad att starta det varje gång.
Det finns dock en rad funktioner inbyggda i exiftool så att du kan köra den som en one-liner för att behandla en hel mapphierarki i ett svep, då får man inte prestandakostnaden eftersom programmet bara exekveras en enda gång.

I ditt fall, om du har diskutrymme för dubbel uppsättning av alla stora bildfiler samtidigt under en stund, då kan du göra så här:

Kod: Markera allt

cd /home/erik/Bilder/ASUS/Bilder/2019/Samsung_S8/
mkdir krymp3
cp *.jpg krymp3
cd krymp3
mogrify -resize 640x480 *.jpg
Du behöver inte loopa något, och du behöver inte fippla med mapp- och filnamn.
Maalobs
Inlägg: 1299
Blev medlem: 3 februari 2005, 14:35:15
Ort: Stockholm

Re: Python, process Killed, kartor med bilder och marker

Inlägg av Maalobs »

Jag kan inte Python, men i din exif_test() har du:

Kod: Markera allt

try:
         with open(path+file_jpg, 'rb') as image_file:
            my_image = Image(image_file)
Öppnar inte det där filen och laddar sedan in hela filens innehåll i en variabel eller ett objekt?
Sedan kör du exif_test() i din while-loop.

Det finns ingen explicit close av filen eller destruction av objektet.
Sker det implicit när filen och objektet faller out-of-scope när loopens aktuella iteration avslutas?
Om det inte sker automagiskt, innebär inte det att du ackumulerar 18000 öppna filehandles och "stora" bildfiler i minnet samtidigt?
xxargs
Inlägg: 10185
Blev medlem: 23 september 2006, 14:28:27
Ort: Södertälje

Re: Python, process Killed, kartor med bilder och marker

Inlägg av xxargs »

Antar att du kör i linux...

Installera och dra igång 'atop' i en terminalfönster (så bred som möjligt och gärna några rader till än default) och kika om process sticker iväg i minnesförbrukning - Linux har en begränsning i hur mycket en program få hugga minne gentemot mängden tillgängligt minne och allokerar programmet mer än detta så får man just detta med dödad process utan vidare förklaring.

med 'atop -fF 1' så finns i övre högra hörnet en post som heter vmlim som i princip sätter taket för hur mycket en process får käka i minne innan det dödas och det brukar vara typiskt halva mängden RAM-minne i datorn om du inte har någon swap aktiv.

Förutom att skruva i kärnans parametrar så brukar det vara enklare att addera på swapfil i en eller flera stycken och då ökas vmlim i samma grad och kan bli större än mängden fysisk RAM i din dator

detta kan göras följande för exempelvis 4GB stor swap:

dd if=/dev/zero of=filnamn bs=1024k count=4096 status=progress
mkswap filnamn
swapon filnamn

(nej, det går inte med 'truncate' - filen måste vara fylld med något (som '0') och inte har 'hål' som truncate skapar - därav användning med 'dd')

och du i atop ser efter det att du fått 4GB swap-minne - du kan lägga på fler likadana filer efter behov med swapon eller att du ser att swapen håller på att ta slut.

nu är linuxkerneln generellt väldigt ovillig att använda swap alls över huvud taget och ser det nästan som last resort, så det här är en mer formell grej och i flesta fallen kan man lägga swap-filen på långsam snurrdisk utan att förvänta sig IO-starving mot disken (trashing även kallat) om man har ont om plats på sin SSD/NVMe-lagring för att kärnan skall övertygas att släppa till mer minne för processer/program innan det nackar denna.
guckrum
Inlägg: 1691
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Python, process Killed, kartor med bilder och marker

Inlägg av guckrum »

Det finns ingen explicit close av filen eller destruction av objektet.
Filen stängs automatiskt eftersom det är en context manager variabel. Bildvariablen derefereras ju när den skrivs över, och kommer vid någon punkt att garbage collectas. Att explicit radera den kan naturligtvis vara klokt i allmänhet, men känns spontant "onödigt".
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: Python, process Killed, kartor med bilder och marker

Inlägg av Oltronix »

xxargs: Mina kunskaper om swaping är väl gamla skolbokskunskaper som "är det problem med minnesresurser så swapar processorn ut en process på disken". Och därmed är allt löst. Som vanligt är verkligheten mer komplicerad. Hur stor skall swaparean på disken vara? Jag har någon minnesbild av primärminnens storlek tom dubbla minnets storlek. Rent spontant tycker jag att den inte borde vara större än en process maxstorlek. Och måste man swapa hela processen? Det borde räcka med delar av processen som har vart inaktiv längst.
Skriv svar