emog Posted March 13, 2007 Share Posted March 13, 2007 I would like to scan an image (using PixelGetColor) and store the the locations of the pixels that are of one single particular colour in a single dimensional array.For example, a 5 x 5 pixel image (zoomed in for legibility) consisting of 25 pixels as below:.. I was thinking the best solution would be to convert it to a 1 pixel stream: ... and so from here I would like to have the array look for a colour (let's say black in this case) and output the number of their position, such as:Array[1]=1Array[2]=2Array[3]=4Array[4]=7Array[5]=8Array[6]=10Array[7]=11Array[8]=12Array[9]=14Array[10]=15Array[11]=17Array[12]=23Array[13]=25The array will only need to have as many values as there are black pixels (in this case), hence is dynamic. Or would it be easier (or more efficient) to have an array for the full pixel count (each pixel gets its own array entry, ie the array would consist of 25 values in this case) and simply have a yes/no (1 or 0) for each array value rather than a number, as below?:-Array[1]=1Array[2]=1Array[3]=0Array[4]=1Array[5]=0Array[6]=0Array[7]=1Array[8]=1Array[9]=0Array[10]=1Array[11]=1Array[12]=1Array[13]=0Array[14]=1Array[15]=1Array[16]=0Array[17]=1Array[18]=0Array[19]=0Array[20]=0Array[21]=0Array[22]=0Array[23]=1Array[24]=0Array[25]=1My actual graphic has near 50,000 pixels in total, though, not just 5 x 5 as in the example, so speed in the calculation is everything.The array would only need to be temporary, as the array and its values will be dumped and then reset elsewhere further on in the code. Can arrays be stored in memory (RAM), or do they need to be physically written to a new file? Would an array storing up to 50,000 entries be too much?Many thanks, and any hints appreciated. Link to comment Share on other sites More sharing options...
SadBunny Posted March 13, 2007 Share Posted March 13, 2007 Arrays can be 'remembered' by the program, or written to a file (but if speed is a goal then avoid harddisk usage). 50.000 elements is no problem at all. After some quick binary searching (manually ), I found that the max array is Dim $a[16777215]. That's more than 16 and a half million! That should suit your needs If you want your array to be just as big as the amount of black dots, you could do one of two things:1 - Run through the dots, ReDim your array with one more every time you find one. (See help for redim.)2 - Run through the dots, count the amount of black dots, create an array of that amount, and run through it again filling the array.Though I would prefer the binary array myself. Don't know why exactly, just feels right... Guess it depends on what you want to do with the information I don't know which one is faster, ReDim'ing an array 50000 times or running through 50000 checks two times (resulting in 100000 checks). You might want to test this out. Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
emog Posted March 14, 2007 Author Share Posted March 14, 2007 Nice one, bunny. After thinking about it I went for a single pass Array that starts with one entry and adds any entries as it picks them up. However, I am getting an error and could do with some help debugging if anyone could offer possible hints, please. #include <Array.au3> Dim $PixelArray[1] ;~~ Scanning image and creating an Array for a single colour ;~~ Encodes to a single pixel stream $PixelCounter = 0 $ColourInstances = 0 For $YAxis = $Y1 to $Y2 Step 1 For $XAxis = $X1 to $X2 Step 1 $PixelCounter = $PixelCounter + 1 $SourceColour = PixelGetColor($XAxis, YAxis) If $SourceColour = $ClrPal[$PalletteCounter] Then _ArrayAdd($PixelArray, $PixelCounter) $ColourInstances = $ColourInstances + 1 EndIf Next Next MsgBox(0, "Array colour pixel count", "Instances of coloured pixels in template is: " & $ColourInstances) ;~~~~~~~ End pixel colour array scan ~~~~~~~~ ;~~~~~~~~ RR Array Output ~~~~~~~~~ WinActivate("OutputWindow") WinWaitActive("OutputWindow") ;~~~ decodes and reconstructs back to a 2D image $PixelCounter = 0 For $YAxis = $Y1 to $Y2 Step 1 For $XAxis = $X1 to $X2 Step 1 $PixelCounter = $PixelCounter + 1 >>> If $PixelArray[$PixelCounter] = $PixelCounter Then Mouseclick("left", $XAxis, $YAxis, 1, 0) EndIf Next Next The error I'm getting is: "Error: Array Variable has incorrect number of subscripts or subscript dimension range exceeded." and I added a ">>>" to show the line in question. Am seriously scratching my head as to what could be causing it. Any suggestions/hints much appreciated! Link to comment Share on other sites More sharing options...
emog Posted March 15, 2007 Author Share Posted March 15, 2007 Still having problems trying to debug the array. Any hints anyone could possibly give? Thanks Link to comment Share on other sites More sharing options...
jvanegmond Posted March 15, 2007 Share Posted March 15, 2007 Ok, first of all: Don't do this kind of crazy calculations in AutoIt. This is some crazy binary stuff. Second, create an 50000 element array and read in the values to the array. Considering the history and background of computers this is a more efficient way of doing it. github.com/jvanegmond Link to comment Share on other sites More sharing options...
SadBunny Posted March 15, 2007 Share Posted March 15, 2007 Still having problems trying to debug the array. Any hints anyone could possibly give? Thanks I tried your code, and modified it so that it reads from my desktop (scite was active) and remembers if a pixel is white, and then in the second part make the mouse move to all white pixels found. I needed to do this to be able to test your code. But it gives me no error whatsoever. The code I derived from your test code is: expandcollapse popup#include <Array.au3> Dim $PixelArray[1] ;~~ Scanning image and creating an Array for a single colour ;~~ Encodes to a single pixel stream $X1 = 500 $X2 = 550 $Y1 = 100 $Y2 = 104 $PixelCounter = 0 $ColourInstances = 0 For $YAxis = $Y1 to $Y2 Step 1 For $XAxis = $X1 to $X2 Step 1 $PixelCounter = $PixelCounter + 1 $SourceColour = PixelGetColor($XAxis, $YAxis) If $SourceColour = 16777215 Then _ArrayAdd($PixelArray, $PixelCounter) $ColourInstances = $ColourInstances + 1 EndIf Next Next MsgBox(0, "Array colour pixel count", "Instances of coloured pixels in template is: " & $ColourInstances) ;~~~~~~~ End pixel colour array scan ~~~~~~~~ ;~~~~~~~~ RR Array Output ~~~~~~~~~ ; WinActivate("OutputWindow") ; WinWaitActive("OutputWindow") ;~~~ decodes and reconstructs back to a 2D image $PixelCounter = 0 For $YAxis = $Y1 to $Y2 Step 1 For $XAxis = $X1 to $X2 Step 1 $PixelCounter = $PixelCounter + 1 If $PixelArray[$PixelCounter] = $PixelCounter Then MouseMove($XAxis,$YAxis) EndIf Next Next It works like a charm, as I suspected, because I couldn't foresee a problem with this array... You sure the $PixelArray does not get changed in any part of the code you didn't include? Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
SadBunny Posted March 15, 2007 Share Posted March 15, 2007 But as I said earlier (and I believe Manadar meant this too?), a 50000 element array is probably better then thousands of _addArray operations... Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
emog Posted March 16, 2007 Author Share Posted March 16, 2007 Thanks ever so much. It's taken me a good while but I've nailed it in the end, it was actually another variable that the main Array output loop was reliable on, but which wasn't being reset after every cycle. So I placed it inside the loop so that it was reset after every cycle and all was well. Must say it's been a great lateral-thinking learning process. One thing I found particularly useful is placing MsgBox displays after every command that you're having problems with, so you can follow the execution of the program step by step and find exactly where the code is going wrong. I have also ditched the previous "add array per cycle" routine in favour of a single 50,000 pass array retrieval of all the colours of the pixels in one go, as suggested. Takes less than a second to carry out the scan, and the array export works beautifully. What originally took the program 3 hours to carry out (individually retrieving the colour and position of a pixel and exporting them individually, up to 50,000 times) now takes about 10 minutes for the whole 50,000 pixels using a single scan Array and then dumping the Array in one, as opposed to switching back and forth between windows for every pixel as before. - A literal real-world improvement of ~1800%. And that includes painting in all 200 colours! Dead chuffed. All it needs now is a GUI. Thanks too all, expecially Bunny. Have a great weekend! Link to comment Share on other sites More sharing options...
SadBunny Posted March 17, 2007 Share Posted March 17, 2007 Thanks too all, expecially Bunny. Have a great weekend!Whee! I'm getting all warm inside... Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted March 17, 2007 Moderators Share Posted March 17, 2007 Whee! I'm getting all warm inside... All those shots of Jack make everyone warm inside .... Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
SadBunny Posted March 17, 2007 Share Posted March 17, 2007 (edited) All those shots of Jack make everyone warm inside ....Hmm... Is it that obvious, huh... Edited March 17, 2007 by SadBunny Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now