c# - Can I parallelize image processing with PLINQ? -


i want compare alpha channel 1 image ~1000 other images. compare method looks this:

public static unsafe double similiarity (bitmap a, bitmap b) {     bitmapdata adata = a.lockbits (         new rectangle (0, 0, a.width, a.height),          system.drawing.imaging.imagelockmode.readonly, a.pixelformat);     bitmapdata bdata = b.lockbits (         new rectangle (0, 0, b.width, b.height),          system.drawing.imaging.imagelockmode.readonly, b.pixelformat);     int pixelsize = 4;      double sum = 0;     (int y=0; y<adata.height; y++) {         byte* arow = (byte *)adata.scan0 + (y * adata.stride);         byte* brow = (byte *)bdata.scan0 + (y * bdata.stride);         (int x=0; x<adata.width; x++) {             byte aweight = arow [x * pixelsize + 3];             byte bweight = brow [x * pixelsize + 3];             sum += math.abs (aweight - bweight);         }     }     a.unlockbits (adata);     b.unlockbits (bdata);      return 1 - ((sum / 255) / (a.width * a.height)); } 

i thought simplest way speed computation using plinq:

var list = bitmap img in imagelist.asparallel (similiarity (referenceimage, img) > 0.5) select img; 

but on execution there exception in gdiplus:

system.invalidoperationexception: operation invalid [gdi+ status: win32error]   @ system.drawing.gdiplus.checkstatus (status status) [0x00000] in <filename unknown>:0    @ system.drawing.bitmap.lockbits (rectangle rect, imagelockmode flags, pixelformat format, system.drawing.imaging.bitmapdata bitmapdata) [0x00000] in <filename unknown>:0  

i understand gdiplus must executed in different processes, thought plinq doing so. wrong assumptions?

i suggest separate weight calculation similarity comparison this:

public static unsafe byte[,] getweight(bitmap a) {     bitmapdata adata = a.lockbits(new rectangle(0, 0, a.width, a.height), imagelockmode.readonly, a.pixelformat);     const int pixelsize = 4;      byte[,] weight = new byte[adata.width, adata.height];     (int y = 0; y < adata.height; y++)     {         byte* arow = (byte*)adata.scan0 + (y * adata.stride);         (int x = 0; x < adata.width; x++)         {             byte aweight = arow[x * pixelsize + 3];             weight[x, y] = aweight;         }     }     a.unlockbits(adata);     return weight; }  public static double getsimilarity(byte[,] weightsa, byte[,] weightsb) {     double sum = 0;     int height = weightsa.getlength(1);     int width = weightsa.getlength(0);     (int y = 0; y < height; y++)     {         (int x = 0; x < width; x++)         {             byte aweight = weightsa[x,y];             byte bweight = weightsb[x, y];             sum += math.abs(aweight - bweight);         }     }      return 1 - ((sum / 255) / (width * height)); } 

the call this:

var referenceweigth = getweight(referenceimage);     var list =         imagelist             .asparallel()             .select(image => new {@image = image, @weight = getweight(image)})             .where(imageandweight => getsimilarity(imageandweight.weight, referenceweigth) > 0.5)             .select(imageandweight => imageandweight.image); 

Comments

Popular posts from this blog

c# - SVN Error : "svnadmin: E205000: Too many arguments" -

c# - Copy ObservableCollection to another ObservableCollection -

All overlapping substrings matching a java regex -