Atak_Snajpera
16th January 2013, 14:53
I've written small app to calculate average luma value for specific image. Speed is not bad thanks to Graphics32 (http://graphics32.org/wiki/) library. My Q6600@3Ghz can process 16MPix image in about 20s (with standard not thread safe image component (Synchronize needed) I had to wait 360s! However I would like to speed up everything by using multiple threads. Each thread will process specific area of the picture so on my quad core i could expect 4 times faster processing. Unfortunately even component from Graphics32 does not allow multiple threads. As soon as I activate second thread all color values report just white (255). I even tried working on separate image components and nothing. With one thread everything is ok. So here is my question. What to do to allow multithreaded processing on image? Transfer all data to array?
sample of my code
procedure TForm1.JvWorkerThread1Execute(Sender: TObject; Params: Pointer);
var Luma,AverageLumainRow,Sum,SumOfAverageLumas:double;
R,G,B:Byte;
Color:TColor;
x,y:integer;
begin
Average_color_THREAD1 := 0;
SumOfAverageLumas := 0;
AverageLumainRow := 0;
for y := 0 to 1000 - 1 do
begin
Sum := 0;
for x := 0 to 1000 - 1 do
begin
Color := form1.Image321.Bitmap.Canvas.Pixels[x,y];
R := GetRValue( Color );
G := GetGValue( Color );
B := GetBValue( Color );
Luma := 0.2126 * R + 0.7152 * G + 0.0722 * B; //convert to grey scale using Rec. 709 formula
Sum := Sum + Luma; //sum all luma values in row
end;
AverageLumainRow := Sum / Image_width;
SumOfAverageLumas := SumOfAverageLumas + AverageLumainRow;
end;
Average_color_THREAD1 := SumOfAverageLumas / 1000;
end;
procedure TForm1.JvWorkerThread2Execute(Sender: TObject; Params: Pointer);
var Luma,AverageLumainRow,Sum,SumOfAverageLumas:double;
R,G,B:Byte;
Color:TColor;
x,y:integer;
begin
Average_color_THREAD2 := 0;
SumOfAverageLumas := 0;
AverageLumainRow := 0;
for y := 1000 to 2000 - 1 do
begin
Sum := 0;
for x := 0 to 1000 - 1 do
begin
Color := form1.Image321.Bitmap.Canvas.Pixels[x,y];
R := GetRValue( Color );
G := GetGValue( Color );
B := GetBValue( Color );
Luma := 0.2126 * R + 0.7152 * G + 0.0722 * B; //convert to grey scale using Rec. 709 formula
Sum := Sum + Luma; //sum all luma values in row
end;
AverageLumainRow := Sum / Image_width;
SumOfAverageLumas := SumOfAverageLumas + AverageLumainRow;
end;
Average_color_THREAD2 := SumOfAverageLumas / 1000;
end;
sample of my code
procedure TForm1.JvWorkerThread1Execute(Sender: TObject; Params: Pointer);
var Luma,AverageLumainRow,Sum,SumOfAverageLumas:double;
R,G,B:Byte;
Color:TColor;
x,y:integer;
begin
Average_color_THREAD1 := 0;
SumOfAverageLumas := 0;
AverageLumainRow := 0;
for y := 0 to 1000 - 1 do
begin
Sum := 0;
for x := 0 to 1000 - 1 do
begin
Color := form1.Image321.Bitmap.Canvas.Pixels[x,y];
R := GetRValue( Color );
G := GetGValue( Color );
B := GetBValue( Color );
Luma := 0.2126 * R + 0.7152 * G + 0.0722 * B; //convert to grey scale using Rec. 709 formula
Sum := Sum + Luma; //sum all luma values in row
end;
AverageLumainRow := Sum / Image_width;
SumOfAverageLumas := SumOfAverageLumas + AverageLumainRow;
end;
Average_color_THREAD1 := SumOfAverageLumas / 1000;
end;
procedure TForm1.JvWorkerThread2Execute(Sender: TObject; Params: Pointer);
var Luma,AverageLumainRow,Sum,SumOfAverageLumas:double;
R,G,B:Byte;
Color:TColor;
x,y:integer;
begin
Average_color_THREAD2 := 0;
SumOfAverageLumas := 0;
AverageLumainRow := 0;
for y := 1000 to 2000 - 1 do
begin
Sum := 0;
for x := 0 to 1000 - 1 do
begin
Color := form1.Image321.Bitmap.Canvas.Pixels[x,y];
R := GetRValue( Color );
G := GetGValue( Color );
B := GetBValue( Color );
Luma := 0.2126 * R + 0.7152 * G + 0.0722 * B; //convert to grey scale using Rec. 709 formula
Sum := Sum + Luma; //sum all luma values in row
end;
AverageLumainRow := Sum / Image_width;
SumOfAverageLumas := SumOfAverageLumas + AverageLumainRow;
end;
Average_color_THREAD2 := SumOfAverageLumas / 1000;
end;