Lion66 Posted September 2, 2021 Posted September 2, 2021 10 hours ago, smbape said: 7b is hard to translate since it involves manipulation of vectors and matrix Yeah, there's a lot more work here than the python. How to filter the list of vectors by square area immediately after _cveFindContoursTyped ? Otherwise, must filter before draw each type of profile, if there are more than one in script.
smbape Posted September 2, 2021 Author Posted September 2, 2021 3 hours ago, Lion66 said: How to filter the list of vectors by square area immediately after _cveFindContoursTyped ? What do you mean by filtering by square area? Do you have a pseudo/python code? Can you put your whole file?
Lion66 Posted September 2, 2021 Posted September 2, 2021 What we saw on the previous page: Local $tVectorPointPtr2 = DllStructCreate("ptr value") For $i = 0 To _VectorOfVectorOfPointGetSize($contours) - 1 _VectorOfVectorOfPointGetItemPtr($contours, $i, $tVectorPointPtr2) Local $Area1 = _cveContourAreaTyped("VectorOfPoint", $tVectorPointPtr2.value) If $Area1 < 1000 Then ContinueLoop Else But I want to make this filter once (after _cveFindContoursTyped), change $contours data, and use the modified data to build all types of contours. Is that clear? Thanks.
smbape Posted September 2, 2021 Author Posted September 2, 2021 1 hour ago, Lion66 said: Is that clear? If you mean having a subset of $contours that validates the condition on _cveContourAreaTyped, then it is Local $good_contours = _VectorOfVectorOfPointCreate() Local $tVectorPointPtr2 = DllStructCreate("ptr value") For $i = 0 To _VectorOfVectorOfPointGetSize($contours) - 1 _VectorOfVectorOfPointGetItemPtr($contours, $i, $tVectorPointPtr2) Local $Area1 = _cveContourAreaTyped("VectorOfPoint", $tVectorPointPtr2.value) If $Area1 < 1000 Then ContinueLoop Else _VectorOfVectorOfPointPush($good_contours, $tVectorPointPtr2.value) Lion66 1
Lion66 Posted September 2, 2021 Posted September 2, 2021 Yeah, that's what I wanted. Thank you! I tried to make "8. Minimum Enclosing Circle" and stuck again. Here's my search in the dark. 😞 Local $radius ;Local $box = _cveMatCreate() Local $tVectorPointPtr7 = DllStructCreate("ptr value") For $i = 0 To _VectorOfVectorOfPointGetSize($contours) - 1 _VectorOfVectorOfPointGetItemPtr($contours, $i, $tVectorPointPtr7) Local $center = _cveInputArrayFromVectorOfPoint($tVectorPointPtr7.value) ;Func _cveMinEnclosingCircleTyped($typeOfPoints, $points, $center, $radius) _cveMinEnclosingCircleTyped("VectorOfPoint", $tVectorPointPtr7.value, $center, $radius) ;CvPoint2D32f* center Local $centerV = _VectorOfPointFCreateSize(2) _VectorOfPointFGetItemPtr($centerV, 0, $tVectorPointPtr7) Local $center_x = DllStructCreate($tagCvPoint2D32f, $tVectorPointPtr7.value) _VectorOfPointFGetItemPtr($centerV, 1, $tVectorPointPtr7) Local $center_y = DllStructCreate($tagCvPoint2D32f, $tVectorPointPtr7.value) ;float* radius ;Func _cveCircleTyped($typeOfImg, $img, $center, $radius, $color, $thickness = 1, $lineType = $CV_LINE_8, $shift = 0) _cveCircleTyped("Mat", $img, $centerV, $radius, _cvScalar(0, 255, 0), $CV_FILLED) Next
smbape Posted September 2, 2021 Author Posted September 2, 2021 (edited) 29 minutes ago, Lion66 said: I tried to make "8. Minimum Enclosing Circle" and stuck again. Here's my search in the dark. 😞 I must say that I am really amazed by your desire to learn. If I was a teacher, I would have loved to have a student like you. Keep it up. ; CVAPI(void) cveMinEnclosingCircle(cv::_InputArray* points, CvPoint2D32f* center, float* radius); Local $center = _cvPoint2f() ; equivalent of DllStructCreate($tagCvPoint2D32f) Local $radius = DllStructCreate("float value") _cveMinEnclosingCircleTyped("VectorOfPoint", $tVectorPointPtr.value, $center, $radius) $center = _cvPoint($center.x, $center.y) _cveCircleMat($img, $center, $radius.value, _cvScalar(0,255,0), 2) Edited September 2, 2021 by smbape Lion66 1
smbape Posted September 2, 2021 Author Posted September 2, 2021 I suppose that will do the 9. Local $cvBox2D = DllStructCreate($tagCvBox2D) ; CVAPI(void) cveFitEllipse(cv::_InputArray* points, CvBox2D* box); _cveFitEllipseTyped("VectorOfPoint", $tVectorPointPtr.value, $cvBox2D) ; CVAPI(void) cveEllipse(cv::_InputOutputArray* img, CvPoint* center, CvSize* axes, double angle, double startAngle, double endAngle, const CvScalar* color, int thickness, int lineType, int shift); _cveEllipseMat($img, _cvPoint($cvBox2D.x, $cvBox2D.y), _cvSize($cvBox2D.width / 2, $cvBox2D.height / 2), $cvBox2D.angle, 0, 360, _cvScalar(0,255,0), 2)
Lion66 Posted September 2, 2021 Posted September 2, 2021 (edited) 3 hours ago, smbape said: If I was a teacher, I would have loved to have a student like you. Keep it up. Yes, teacher! 😃 Example 8 is working. 1 hour ago, smbape said: I suppose that will do the 9. You read my thoughts! 😉 But there's a little problem. If the contour is close to the edge of the picture, when trying to create an ellipse, the script is crashes. That's probably what's indicated here (about fitEllipse()): "Developer should keep in mind that it is possible that the returned ellipse/rotatedRect data contains negative indices, due to the data points being close to the border of the containing Mat element.". I don't know what to do, but need to rule out crashes the script. Thank you. Edited September 2, 2021 by Lion66
smbape Posted September 2, 2021 Author Posted September 2, 2021 1 hour ago, Lion66 said: I don't know what to do, but need to rule out crashes the script. I theorized that reducing the ellipse axes will solve the problem. To test the theory, I need a test case. Can you upload a script that crashes in those cases?
Lion66 Posted September 2, 2021 Posted September 2, 2021 If there is such a case, I suggest giving a message to the user and avoiding collapse. Attaching a file. Any threshold (200), your code for ellipse. Since the background is white, the ellipse tend to be out of the picture.
smbape Posted September 2, 2021 Author Posted September 2, 2021 You script crashes for another reason. There should be at least 5 points to fit the ellipse You should add a condition before drawing fitEllipse _VectorOfPointGetSize($tVectorPointPtr.value) >= 5 I found 2 ways to make the script dump errors. set the environment variable OPENCV_DUMP_ERRORS to 1 and restart SciTE. EnvSet within a script does not work. SciTE has to be restarted. I recommend this way because all your scripts will benefit from it. Add the following code in your script Local $hHandle = DllCallbackRegister("onError", "none", "int;ptr;ptr;ptr;int;ptr") _cveRedirectError(DllCallbackGetPtr($hHandle), Null, Null) ; ... Func onError($status, $func_name, $err_msg, $file_name, $line, $user_data) Local $errorStr = CStringToString(_cveErrorStr($status)) $func_name = CStringToString($func_name) $err_msg = CStringToString($err_msg) $file_name = CStringToString($file_name) If $func_name == "" Then $func_name = "unknown function" EndIf ConsoleWrite("OpenCV Error: " & $errorStr & " (" & $err_msg & ") in " & $func_name & ", file " & $file_name & ", line " & $line & "" & @CRLF) EndFunc Func CStringToString($src) Local $sSrcDllType If IsDllStruct($src) Then $sSrcDllType = "struct*" Else $sSrcDllType = "ptr" EndIf Local $strlen = CVEDllCallResult(DllCall("msvcrt.dll", "int:cdecl", "strlen", $sSrcDllType, $src), "strlen", @error) Local $tStr = DllStructCreate("char value[" & $strlen & "]", $src) return $tStr.value EndFunc ;==>CStringToString Lion66 1
Lion66 Posted September 3, 2021 Posted September 3, 2021 (edited) 10 hours ago, smbape said: There should be at least 5 points to fit the ellipse I didn't see it. 10 hours ago, smbape said: _VectorOfPointGetSize($tVectorPointPtr.value) >= 5 It's a decision. 10 hours ago, smbape said: Add the following code in your script Local $hHandle = DllCallbackRegister("onError" This is interesting in that it explains where the error is. But does not prevent the script from collapsing. 10 hours ago, smbape said: set the environment variable OPENCV_DUMP_ERRORS to 1 and restart SciTE. Do need to do this in Windows? I don't like solutions tied to a certain computer. I did and saw no difference. Perhaps because I already used the decision ""Local $hHandle = DllCallbackRegister("onError". Is it possible to replace in _cve freely _cvScalar(0, 255, 0) to _cvRGB(0, 255, 0). And vice versa? Thank you. Edited September 3, 2021 by Lion66
smbape Posted September 3, 2021 Author Posted September 3, 2021 (edited) 51 minutes ago, Lion66 said: Do need to do this in Windows? I don't like solutions tied to a certain computer. Well, you either set it in windows or in a command prompt, then start SciTE from that command prompt. Usually, using EnvSet does the trick, but not in this case. 51 minutes ago, Lion66 said: I did and saw no difference. Perhaps because I already used the decision ""Local $hHandle = DllCallbackRegister("onError". Yes, using _cveRedirectError makes your function to be called instead of the default callback which logs the same error. 51 minutes ago, Lion66 said: I didn't see it. This is suprising. Once you activate OPENCV_DUMP_ERRORS, there should be in the console the error OpenCV(4.5.3) Error: Incorrect size of input array (There should be at least 5 points to fit the ellipse) in cv::fitEllipseNoDirect 51 minutes ago, Lion66 said: It's a decision. I will rather say it is a consequence. If you don't want your script to crash because of the error "There should be at least 5 points to fit the ellipse", you have to check that you have at least 5 points before computing fitEllipse 51 minutes ago, Lion66 said: This is interesting in that it explains where the error is. But does not prevent the script from collapsing. The only way to prevent a script from crashing is to handle errors that occurs. For example, the following script will crash Local $arr[1] $arr[2] = 1 What could be the universal solution that will not make it crash? Should we continue the script after not making it crash? A universal solution cannot decide that for you. Edited September 3, 2021 by smbape
Lion66 Posted September 3, 2021 Posted September 3, 2021 (edited) 1 hour ago, Lion66 said: I didn't see it. It meant I didn't see it in the documentation before you pointed it out. What about 1 hour ago, Lion66 said: Is it possible to replace in _cve freely _cvScalar(0, 255, 0) to _cvRGB(0, 255, 0). And vice versa? ;;;; Thanks. Edited September 3, 2021 by Lion66
Lion66 Posted September 3, 2021 Posted September 3, 2021 1 hour ago, smbape said: The only way to prevent a script from crashing is to handle errors that occurs. I understand that if you assume a mistake, then it can be processed. But when they have already learned a mistake, the script crashes. Or is it possible to do something?
smbape Posted September 3, 2021 Author Posted September 3, 2021 1 hour ago, Lion66 said: Is it possible to replace in _cve freely _cvScalar(0, 255, 0) to _cvRGB(0, 255, 0). And vice versa? Oh sorry, I missed that question. No, _cvScalar can be seen as _cvBRGA. The first parameter is blue, the second is red, the third is green and the fourth is the opacity. In AutoIt, we are used to RGB notation, that's why there is the convenient function _cvRGB. Examples on the internet uses _cvScalar
smbape Posted September 3, 2021 Author Posted September 3, 2021 4 minutes ago, Lion66 said: But when they have already learned a mistake, the script crashes. Or is it possible to do something? I don't understand the question. The script crashes when it encounters an error. Who is "they" in "they have already learned a mistake" ? The users or the scripts? If it is the users, you can't do anything about that.
Lion66 Posted September 3, 2021 Posted September 3, 2021 (edited) I meant that if an unaccounted error occurs, it would be good to intercept the event, send message to user and get back into the main loop. Instead of collapse. Thanks. Edited September 3, 2021 by Lion66
smbape Posted September 3, 2021 Author Posted September 3, 2021 (edited) When you say get back into the main loop, what do you expect the program to do: Continue the loop. What if your program uses results of the previous loop? Exit the loop. What if the process after the loop uses results of the previous loop? I don't think it is possible in synchronous execution like in AutoIt. In nodejs it is possible because it is asynchronous. When an unexpected error occurs, the current event loop is stopped, and nodejs goes to the next event loop. Edited September 3, 2021 by smbape
Lion66 Posted September 3, 2021 Posted September 3, 2021 Thanks for the answer. You understand more deeply than I do. I'd rather Exit the loop. as "Return" or "Exit loop".
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