Тема: AHK: OpenCV определение лица
Публикую, чисто в образовательных целях.
Удобней использовать OpenCV com:
http://forum.script-coding.com/viewtopic.php?id=17642
Перенес код с AutoIt:
https://www.autoitscript.com/forum/topi … nt-1305145
Используется 4 dll 2413.6 версии:
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/opencv … win/2.4.13
Лежат для 32бит:
opencv-2.4.13.6-vc14\opencv\build\x86\vc14\bin\
Для 64бит:
opencv-2.4.13.6-vc14\opencv\build\x64\vc14\bin\
haarcascade_frontalface_default.xml лежит в
opencv-2.4.13.6-vc14\opencv\sources\data\haarcascades_GPU\haarcascade_frontalface_default.xml
Код:
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
}
Код по поиску совпадений картинок через openCV.
Функции нужно скопировать с предыдущего кода.
Перенес отсюда:
https://www.autoitscript.com/forum/topi … nt-1280955
Код с threshold = 0.9:
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