therks Posted February 27, 2020 Posted February 27, 2020 So I don't have any code cooked up yet as this is still in the theoretical stage. Just looking for some advice. My current idea is to resize the image to 1x1 pixel, probably using _GDIPlus_ImageResize, and read the color of the resulting pixel to obtain an admittedly very general sense of brightness. Does anyone think this could work? We have a CCTV system running at home using some home made cameras (raspberry pi) and we're trying to automate toggling settings for day/night time. We started with an AutoIt script that checked sunrise and sundown times for our location (calculations pulled from here) and toggled the settings based on that. Unfortunately our weather varies wildly, so it can get light/dark far outside normal sunrise/sundown times. Now we're hoping to periodically grab a still from the camera and toggle the light mode based on that. My AutoIt Stuff | My Github
Nine Posted February 27, 2020 Posted February 27, 2020 I would go with something like this : #include <Constants.au3> #include <GDIPlus.au3> _GDIPlus_Startup () $hBitmap = _GDIPlus_BitmapCreateFromFile ("Image.jpg") $hBitMapResized = _GDIPlus_ImageResize ($hBitmap, 20, 20) $tBitmapData = _GDIPlus_BitmapLockBits ($hBitMapResized, 0, 0, 20, 20, $GDIP_ILMREAD, $GDIP_PXF32ARGB) $iScan0 = DllStructGetData($tBitmapData, "Scan0") $tPixel = DllStructCreate("int[400];", $iScan0) Local $iMean = 0, $iStdDev = 0, $r, $g, $b For $i = 1 to 400 Split (DllStructGetData ($tPixel, 1, $i), $r, $g, $b) $iMean += $r+$g+$b Next $iMean /= 1200 For $i = 1 to 400 Split (DllStructGetData ($tPixel, 1, $i), $r, $g, $b) $iStdDev += ($r-$iMean)^2 $iStdDev += ($g-$iMean)^2 $iStdDev += ($b-$iMean)^2 Next $iStdDev = Sqrt($iStdDev/1200) MsgBox ($MB_SYSTEMMODAL,"",$iMean & "/" & $iStdDev) _GDIPlus_BitmapUnlockBits($hBitMapResized, $tBitmapData) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_BitmapDispose($hBitMapResized) _GDIPlus_Shutdown () Func Split ($c, ByRef $r, ByRef $g, ByRef $b) $r = bitshift(bitand ($c,0xff0000),16) $g = bitshift(bitand ($c,0xff00),8) $b = bitand ($c,0xff) EndFunc Where the mean should be low for darker image and Standard Deviation also low for darker. I'm applying it for each component RGB, because global color doesn't say much. Also going with a single (or a few) value, you will loose the StdDev significance. I don't think anyone will argue that the lower is the mean (closer to 0), it implies that the image is quite dark. But even with a somewhat low mean, if you got a high StdDev, it implies that there is high contrast. I would assume there is some brightness although part of the image is black. So StdDev must be low as well. Of course this is untested, and you will have to adjust the threshold of those indicator to fit your requirements. Hope that make sense. therks 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
RTFC Posted February 28, 2020 Posted February 28, 2020 (edited) @Nine: you're skipping half the outer rim of the image (range 0-20 = 21 pixels per side = 441 squared). Also, you lose one degree of freedom in calculating the mean, so you should divide by (3x441) - 1 = 1,323 -1 = 1322. Edited February 28, 2020 by RTFC My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O
Nine Posted February 28, 2020 Posted February 28, 2020 @RTFC. It is not a range, it is a width and a height. Major difference, so my code is good. If you are still unsure use this code : $tBitmapData = _GDIPlus_BitmapLockBits ($hBitMapResized, 0, 0, 20, 20, $GDIP_ILMREAD, $GDIP_PXF32ARGB) ;Global Const $tagGDIPBITMAPDATA = "uint Width;uint Height;int Stride;int Format;ptr Scan0;uint_ptr Reserved" $iScan0 = DllStructGetData($tBitmapData, "Scan0") $iW = DllStructGetData($tBitmapData, "Width") $iH = DllStructGetData($tBitmapData, "Height") $iS = DllStructGetData($tBitmapData, "Stride") ConsoleWrite ($iW & "/" & $iH & "/" & $iS & @CRLF) “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
RTFC Posted February 28, 2020 Posted February 28, 2020 Please excuse the brainfart; mixing up languages again. My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O
therks Posted March 1, 2020 Author Posted March 1, 2020 Well I appreciate the code there @Nine, but I was offline for a few days and cooked this up in the meantime. Func _GetImageBrightness($sFile) ; Return: 0 black -> 100 white Local $hBitmap, $hBitMapResized, $iColor, $R, $G, $B $hBitmap = _GDIPlus_BitmapCreateFromFile($sFile) $hBitMapResized = _GDIPlus_ImageResize($hBitmap, 1, 1) $iColor = BitAND(_GDIPlus_BitmapGetPixel($hBitMapResized, 0, 0), 0xffffff) $R = BitShift(BitAND($iColor, 0xff0000), 16) $G = BitShift(BitAND($iColor, 0xff00), 8) $B = BitAND($iColor, 0xff) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_BitmapDispose($hBitMapResized) Return SetExtended($iColor, Sqrt( .241 * $R ^ 2 + .691 * $G ^ 2 + .068 * $B ^ 2 ) / 2.55) EndFunc It's not as thorough as yours, but in a few simple tests it seems to be working out alright. I'm combining this with a set of thresholds to determine when to activate either day or night mode on our cameras. The calculation for brightness came from here. My AutoIt Stuff | My Github
Nine Posted March 1, 2020 Posted March 1, 2020 Interesting, I'll keep that calculation in mind... “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
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