Number of images on the screen Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
Loop
Posts: 64
Joined: 07 Jan 2019, 14:51

Number of images on the screen

25 Oct 2019, 14:38

Hi
How can I find out how many images are on the screen?
for example:
On this picture there are 3 fishes, how can i find out this with aHk?
fish.png
fish.png (13.48 KiB) Viewed 1605 times
Thx
ymnmwpu7
Posts: 12
Joined: 25 Oct 2019, 20:15

Re: Number of images on the screen

25 Oct 2019, 20:48

AHK isn't really meant for this kind of thing but here is how you would do it:
(you can only use this method if you know what picture you're looking for)
1, convert the image to bitmap format
2, convert bitmap format to a hex string
3, use a long chain of if statements checking to see if the pattern of hex color codes perfectly matches the picture you're looking for
4, NumberOfImages++

Yeah, I wouldn't recommend doing this in AHK
User avatar
Chunjee
Posts: 707
Joined: 18 Apr 2014, 19:05
GitHub: Chunjee

Re: Number of images on the screen  Topic is solved

27 Oct 2019, 12:17

There is a function called FindClick and one of the features is "Find all instances of an image"

Thread: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=18719
swagfag
Posts: 4070
Joined: 11 Jan 2017, 17:59

Re: Number of images on the screen

27 Oct 2019, 12:41

if fish of discrete proportions are only ever gonna spawn, obtain an image of each and Gdip_ImageSearch for them as many times as there are images, then sum all occurrences
another alternative would be to try something with *TransN that would match the smallest possible fish(but i can imagine how this could lead to more false positives)
Spoiler
i agree that this would be kinda pain in the ass to do with AHK, id do it with py and opencv instead: find aspect ratio of fish, find axis aligned bounding boxes, check if bounding box ratio resembles fish ratio, if it does -> fish++
Loop
Posts: 64
Joined: 07 Jan 2019, 14:51

Re: Number of images on the screen

28 Oct 2019, 11:02

Chunjee wrote:
27 Oct 2019, 12:17
There is a function called FindClick and one of the features is "Find all instances of an image"

Thread: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=18719
Thank you,
Is there any possibility to deactivate Mouse movement?

Code: Select all

MsgBox, % FindClick("myimg.png", "e Count=1 n=0")
User avatar
Chunjee
Posts: 707
Joined: 18 Apr 2014, 19:05
GitHub: Chunjee

Re: Number of images on the screen

29 Oct 2019, 14:29

Loop wrote:
28 Oct 2019, 11:02
Thank you,
Is there any possibility to deactivate Mouse movement?
I've never used it but I believe the option is "n0" or 0 clicks. If I am reading the documentation correctly "n" would also work.
malcev
Posts: 798
Joined: 12 Aug 2014, 12:37

Re: Number of images on the screen

04 Nov 2019, 22:59

About OpenCV.
Code from AutoIt - Face Recognition
https://www.autoitscript.com/forum/topic/160732-opencv-udf/page/2/?tab=comments#comment-1305145
Needed 4 dll 2413.6 version.
Global opencv := { opencv_core: "opencv_core2413.dll"
, opencv_highgui: "opencv_highgui2413.dll"
, opencv_imgproc: "opencv_imgproc2413.dll"
, opencv_objdetect: "opencv_objdetect2413.dll" }
https://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.4.13
For 32 bit here:
opencv-2.4.13.6-vc14\opencv\build\x86\vc14\bin\
For 64 bit here:
opencv-2.4.13.6-vc14\opencv\build\x64\vc14\bin\
haarcascade_frontalface_default.xml here:
opencv-2.4.13.6-vc14\opencv\sources\data\haarcascades_GPU\haarcascade_frontalface_default.xml

Code: Select all

file := "lena.jpg"
window := "gui"
haarcascade := "haarcascade_frontalface_default.xml"
scale := 1.3


;start dll opencv
Global opencv := { opencv_core: "opencv_core2413.dll" 
, opencv_highgui: "opencv_highgui2413.dll"
, opencv_imgproc: "opencv_imgproc2413.dll"
, opencv_objdetect: "opencv_objdetect2413.dll" }
_OpenCV_Startup()

;//load haar data
cascade := _cvLoad(haarcascade)

;// load IPL type image
pimg := _cvLoadImage(file)

;// show our input image
_cvShowImage(window, pimg)

;// Create destination images
pimgGrayScale := _cvCreateImage(_cvGetSize(pimg, width, height), 8, 1)
pimgsmall := _cvCreateImage(_cvSize(Round(width/scale), Round(height/scale)), 8, 1)

;//converting the original image into grayscale, resize, and equalize
_cvCvtColor(pimg, pimgGrayScale, CV_BGR2GRAY := 6)
_cvResize(pimgGrayScale, pimgsmall, CV_INTER_LINEAR := 1)
_cvEqualizeHist(pimgsmall, pimgsmall)

; //setup memory block for sequence storage
pstorage := _cvCreateMemStorage(0)   ; //storage area for all contours
_cvClearMemStorage(pstorage)

;// Detect features using haar cascades store as CvSeq
objects := _cvHaarDetectObjects(pimgsmall, cascade, pstorage, 1.1, 8, 0, _cvSize(30, 30))

;// Draw rectangles around detected features
loop % NumGet(objects+0, 8+A_PtrSize*4, "int")   ;  total found
{
   r := _cvGetSeqElem(objects, A_Index)
   x := NumGet(r+0, 0, "int")*scale
   y := NumGet(r+0, 4, "int")*scale
   w := NumGet(r+0, 8, "int")*scale
   h := NumGet(r+0, 12, "int")*scale
   _cvRectangle(pimg, _cvPoint(x, y), _cvPoint(x+w, y+h), _CV_RGB(vScalar, 255, 0, 0), 2, 8, 0)

   ;// Update input image
   _cvShowImage(window, pimg)
}
msgbox done

_cvReleaseImage(pimgsmall)
_cvReleaseImage(pimgGrayScale)
_cvReleaseImage(pimg)
_cvDestroyAllWindows()
_cvClearMemStorage(pstorage)
_cvClearSeq(objects)
_Opencv_CloseDLL()
ExitApp






_OpenCV_Startup()
{
   For key, value in opencv
      DllCall("LoadLibrary", "Str", value, "Ptr")
}

_cvLoadImage(filename, iscolor := 1)  ;  CV_LOAD_IMAGE_COLOR
{
   Result := DllCall(opencv.opencv_highgui "\cvLoadImage", "AStr", filename, "int", iscolor, "Cdecl ptr")
   if !Result or ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
   return Result
}

_cvNamedWindow(name, flags := 0x00000001)   ;   CV_WINDOW_AUTOSIZE 
{
   DllCall(opencv.opencv_highgui "\cvNamedWindow", "AStr", name, "int", flags, "Cdecl ptr")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvShowImage(name, pimage)
{
   DllCall(opencv.opencv_highgui "\cvShowImage", "AStr", name, "ptr", pimage, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvGetSize(pimage, ByRef width := 0, ByRef height := 0)
{
   WidthHeight := DllCall(opencv.opencv_core "\cvGetSize", "ptr", pimage, "Cdecl int64")
   width := 0xFFFFFFFF & WidthHeight
   height := WidthHeight >> 32
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
   return WidthHeight
}

_cvCreateMat(cvrows, cvcols, cvtype)
{
   Result := DllCall(opencv.opencv_core "\cvCreateMat", "int", cvrows, "int", cvcols, "int", cvtype, "Cdecl ptr")
   if !Result or ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
   return Result
}

_cvMatchTemplate(cvimage, cvtempl, cvresult, cvmethod)
{
   DllCall(opencv.opencv_imgproc "\cvMatchTemplate", "ptr", cvimage, "ptr", cvtempl, "ptr", cvresult, "int", cvmethod, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvNormalize(cvsrc, cvdst, cva, cvb, cvnorm_type, cvmask)
{
   DllCall(opencv.opencv_core "\cvNormalize", "ptr", cvsrc, "ptr", cvdst, "Double", cva, "Double", cvb, "int", cvnorm_type, "ptr", cvmask, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvThreshold(cvsrc, cvdst, cvthreshold, cvmax_value, cvthreshold_type)
{
   DllCall(opencv.opencv_imgproc "\cvThreshold", "ptr", cvsrc, "ptr", cvdst, "Double", cvthreshold, "Double", cvmax_value, "int", cvthreshold_type, "Cdecl double")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvSize(width, height)
{
   return width&0xFFFFFFFF|height<<32
}

_cvPoint(x, y)
{
   return x&0xFFFFFFFF|y<<32
}

_cvCreateImage(cvsize, cvdepth, cvchannels)
{
   Result := DllCall(opencv.opencv_core "\cvCreateImage", "int64", cvsize, "int", cvdepth, "int", cvchannels, "Cdecl ptr")
   if !Result or ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
   return Result
}

_cvArrTohBitmap(pimage, byref width = "", byref height = "") { 
	Result := _cvCreateImage(_cvGetSize(pimage, width, height), 8, 4)
	_cvCvtColor(pimage, Result, 0)  
	pData := NumGet(Result + 0, 68 + 20 * (A_PtrSize = 8), "Ptr")
	hBitmap := DllCall("CreateBitmap", "Int", width, "Int", height, "UInt", 1, "UInt", 32, "Ptr", pData)
	Return hBitmap, _cvReleaseImage(Result)
}

_cvScalar(ByRef vScalar, value)
{
   VarSetCapacity(vScalar, 32, 0)
   if IsObject(value)
   {
      loop 4
         NumPut(value%A_Index%, vScalar, (A_Index-1)*8, "double")
   }
   else
   {
      loop 4
         NumPut(value, vScalar, (A_Index-1)*8, "double")
   }
   return &vScalar
}

_CV_RGB(ByRef vScalar, cvRed, cvGreen, cvBlue)
{
   VarSetCapacity(vScalar, 32, 0)
   NumPut(cvBlue, vScalar, 0, "double")
   NumPut(cvGreen, vScalar, 8, "double")
   NumPut(cvRed, vScalar, 16, "double")
   NumPut(0, vScalar, 24, "double")
   return &vScalar
}

_cvSet(cvarr, cvvalue, cvmask := 0)
{
   if (A_PtrSize = 4)
      DllCall(opencv.opencv_core "\cvSet", "ptr", cvarr, "double", NumGet(cvvalue+0, 0, "double"), "double", NumGet(cvvalue+0, 8, "double"), "double", NumGet(cvvalue+0, 16, "double"), "double", NumGet(cvvalue+0, 24, "double"), "ptr", cvmask, "Cdecl")
   else
      DllCall(opencv.opencv_core "\cvSet", "ptr", cvarr, "ptr", cvvalue, "ptr", cvmask, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvMinMaxLoc(cvarr, cvmin_val, cvmax_val, cvmin_loc, cvmax_loc, cvmask)
{
   DllCall(opencv.opencv_core "\cvMinMaxLoc", "ptr", cvarr, "ptr", cvmin_val, "ptr", cvmax_val, "ptr", cvmin_loc, "ptr", cvmax_loc, "ptr", cvmask, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvRectangle(cvimg, cvpt1, cvpt2, cvcolor, cvthickness, cvline_type, cvshift)
{
   if (A_PtrSize = 4)
      DllCall(opencv.opencv_core "\cvRectangle", "ptr", cvimg, "int64", cvpt1, "int64", cvpt2, "double", NumGet(cvcolor+0, 0, "double"), "double", NumGet(cvcolor+0, 8, "double"), "double", NumGet(cvcolor+0, 16, "double"), "double", NumGet(cvcolor+0, 24, "double"), "int", cvthickness, "int", cvline_type, "int", cvshift, "Cdecl")
   else
      DllCall(opencv.opencv_core "\cvRectangle", "ptr", cvimg, "int64", cvpt1, "int64", cvpt2, "ptr", cvcolor, "int", cvthickness, "int", cvline_type, "int", cvshift, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvCvtColor(cvsrc, cvdst, cvcode)
{
   DllCall(opencv.opencv_imgproc "\cvCvtColor", "ptr", cvsrc, "ptr", cvdst, "int", cvcode, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvResize(cvsrc, cvdst, cvinterpolation := 1)   ; CV_INTER_LINEAR
{
   DllCall(opencv.opencv_imgproc "\cvResize", "ptr", cvsrc, "ptr", cvdst, "int", cvinterpolation, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvEqualizeHist(cvsrc, cvdst)
{
   DllCall(opencv.opencv_imgproc "\cvEqualizeHist", "ptr", cvsrc, "ptr", cvdst, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvLoad(cvfilename, cvmemstorage := 0, cvname := 0, cvreal_name := 0)
{
   Result := DllCall(opencv.opencv_core "\cvLoad", "AStr", cvfilename, "ptr", cvmemstorage, "ptr", cvname, "ptr", cvreal_name, "Cdecl ptr")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
   return Result
}

_cvCreateMemStorage(cvblock_size)
{
   Result := DllCall(opencv.opencv_core "\cvCreateMemStorage", "int", cvblock_size, "Cdecl ptr")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
   return Result
}

_cvClearMemStorage(cvstorage)
{
   DllCall(opencv.opencv_core "\cvClearMemStorage", "ptr", cvstorage, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvHaarDetectObjects(cvimage, cvcascade, cvstorage, cvscale_factor := 1.1, cvmin_neighbors := 3, cvflags := 0, cvmin_size := 0, cvmax_size := 0)
{
   Result := DllCall(opencv.opencv_objdetect "\cvHaarDetectObjects", "ptr", cvimage, "ptr", cvcascade, "ptr", cvstorage, "double", cvscale_factor, "int", cvmin_neighbors, "int", cvflags, "int64", cvmin_size, "int64", cvmax_size, "Cdecl ptr")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
   return Result
}

_cvGetSeqElem(cvseq, cvindex)
{
   Result := DllCall(opencv.opencv_core "\cvGetSeqElem", "ptr", cvseq, "int", cvindex, "Cdecl ptr")
   if !Result or ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
   return Result
}

_cvReleaseImage(pimage)
{
   DllCall(opencv.opencv_core "\cvReleaseImage", "ptr*", pimage, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvReleaseMat(cvmat)
{
   DllCall(opencv.opencv_core "\cvReleaseMat", "ptr*", cvmat, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvDestroyAllWindows()
{
   DllCall(opencv.opencv_highgui "\cvDestroyAllWindows", "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_cvClearSeq(cvseq)
{
   DllCall(opencv.opencv_core "\cvClearSeq", "ptr", cvseq, "Cdecl")
   if ErrorLevel
      _Error(A_ThisFunc "`n" ErrorLevel)
}

_Opencv_CloseDLL()
{
   For key, value in opencv
      if hModule := DllCall("GetModuleHandle", "str", value)
         DllCall("FreeLibrary", "ptr", hModule)
}

_Error(val)
{
   msgbox % val "`nLastError - " A_LastError
   ExitApp
}
The next code searches similiar images with threshold = 0.9:.
You have to copy functions from 1 example.
https://www.autoitscript.com/forum/topic/160732-opencv-udf/?page=2&tab=comments#comment-1280955

Code: Select all

file1 := "1.jpg"
file2 := "2.jpg"
window := "gui"

;start dll opencv
Global opencv := { opencv_core: "opencv_core2413.dll" 
, opencv_highgui: "opencv_highgui2413.dll"
, opencv_imgproc: "opencv_imgproc2413.dll" }
_OpenCV_Startup()

;// load IPL type image both images must have same number of bits and color channels!
pimg := _cvLoadImage(file1)
ptemp := _cvLoadImage(file2) ;image to look for

;// Create some windows to show the input and output images in.
_cvNamedWindow(window)

;// show our input image
_cvShowImage(window, pimg)

;// Determine images height and width to create results matrix
_cvGetSize(pimg, width, height)
_cvGetSize(ptemp, width2, height2)
rw :=  width - width2 + 1
rh :=  height - height2 + 1

;// Create Opencv matrix object 32 bit floating
presult := _cvCreateMat(rh, rw, CV_32FC1 := 5)

;// Template matching
_cvMatchTemplate(pimg, ptemp, presult, CV_TM_CCOEFF_NORMED := 5)
_cvNormalize(presult, presult, 0, CV_C := 1, CV_MINMAX := 32, 0)
_cvThreshold(presult, presult, thresh := 0.9, maxval := 1, CV_THRESH_BINARY := 0)

;//locate matches
;
;// Create minmax variables to pass to opencv
VarSetCapacity(pmaxloc, 8, 0)
VarSetCapacity(pminloc, 8, 0)
VarSetCapacity(pmaxval, 8, 0)
VarSetCapacity(pminval, 8, 0)

;// create mask to find multiple matches
pmask := _cvCreateImage(_cvSize(rw, rh), IPL_DEPTH_8U := 8, channels := 1)
_cvSet(pmask, _cvScalar(vScalar, 1))

;// Find location of maximum
_cvMinMaxLoc(presult, &pminval, &pmaxval, &pminloc, &pmaxloc, pmask)

loop
{
   ;// Mask it to find others if exists and draw red rectangle on input image
   _cvRectangle(pmask, _cvPoint(NumGet(pmaxloc, 0, "int")-5, NumGet(pmaxloc, 4, "int")-5), _cvPoint(NumGet(pmaxloc, 0, "int")+ width2, NumGet(pmaxloc, 4, "int")+height2), _cvScalar(vScalar, 0), -1, 8, 0)
   _cvRectangle(pimg, _cvPoint(NumGet(pmaxloc, 0, "int")-5, NumGet(pmaxloc, 4, "int")-5), _cvPoint(NumGet(pmaxloc, 0, "int")+ width2+10, NumGet(pmaxloc, 4, "int")+height2+10), _CV_RGB(vScalar, 255, 0, 0), 2, 8, 0)

   ;// Update input image
   _cvShowImage(window, pimg)

   ;// Find location of maximum
   _cvMinMaxLoc(presult, &pminval, &pmaxval, &pminloc, &pmaxloc, pmask)
   if (NumGet(pmaxval, 0, "double") < 0.99)
      break
   sleep 1000
}
msgbox done
_cvReleaseImage(pmask)
_cvReleaseMat(presult)
_cvReleaseImage(ptemp)
_cvReleaseImage(pimg)
_cvDestroyAllWindows()
_Opencv_CloseDLL()
ExitApp

Return to “Ask For Help”

Who is online

Users browsing this forum: Bad husband, mikeyww, SleepMoover and 32 guests