#Region Module Attributes
#FullScreen: False
#IncludeTitle: False
#ApplicationLabel: OCV BlobDetector
#VersionCode: 5
#VersionName:
#SupportedOrientations: landscape
#CanInstallToExternalStorage: False
#End Region
'======================================================================================
' Version history
' 1. -First version
' 2. -Forces camera to work 480x640. In previous version it was assuming so, but crashed on devices where it did not happen (Samsung S6)
' -(Good practices) All OCV objects needed in the main processing loop (camera preview) are initialized before and reused.
' 3 -Version 2 solution for camera size was not correct. Fixed
'======================================================================================
'======================================================================================
' BlobDetector example
' Point with the camera to a large-enough colored object (better if it has big contrast with the rest of the image) and tap onto it
' Based on its mean color, it will detect the biggest color blob with a similar color and draw a square on it
'======================================================================================
'Activity module
Sub Process_Globals
Private frontCamera As Boolean = False
End Sub
Sub Globals
Private Panel1 As Panel
Private camEx As CameraExClass
Dim DESIREDCAMERAWIDTH As Int = 640 'Set it to a resolution that your camera supports. 640x480 is more than enough to detect color blobs in most cases.
Dim DESIREDCAMERAHEIGHT As Int =480
Dim PreviewWidth As Int ' Preview width and Height related to camera own orientation
Dim PreviewHeight As Int
Dim PreviewScreenWidth As Int ' Prevew width and height in screen
Dim PreviewScreenHeight As Int
Dim myBitmap(1) As Bitmap
Dim myIV(1) As ImageView
'OCV
Dim ocl As OCVOpenCVLoader
Dim mCvt As OCVCvType
Dim mUtils As OCVUtils
Dim mImgProc As OCVImgproc
'BLobDetectorActivity
Private mIsColorSelected As Boolean=False
Private mYuvImage As OCVMat
Private mRgba As OCVMat
Private mBlobColorRgba As OCVScalar
Private mBlobColorHsv As OCVScalar
Private mDetector As clBLobDetector
Private mSpectrum As OCVMat
Private SPECTRUM_SIZE As OCVSize
Private CONTOUR_COLOR As OCVScalar
Private ROTATED_CONTOUR_COLOR As OCVScalar
Dim CameraBmp As DJIFPVWidget
Private timer1 As Timer
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("1")
myIV(0).Initialize("")
myIV(0).Gravity=Gravity.FILL
Dim HI As Int =100%Y
Dim WI As Int=HI*DESIREDCAMERAWIDTH/DESIREDCAMERAHEIGHT 'keep aspect ratio
Panel1.SetLayout(0, 0,WI,HI)
Activity.AddView(myIV(0),0,0,WI,HI)
timer1.Initialize("timer1", 30)
End Sub
Sub Activity_Resume
' InitializeCamera
End Sub
Private Sub InitializeCamera
' camEx.Initialize(Panel1, frontCamera, Me, "Camera1")
' frontCamera = camEx.Front
End Sub
Sub Activity_Pause (UserClosed As Boolean)
' camEx.Release
End Sub
Sub Camera1_Ready (Success As Boolean)
If Success Then
PreviewWidth = 640 '640?
PreviewHeight = 480
'Create the bitmap in display orientatiom
'If ((PreviewWidth>PreviewHeight) And (100%X>100%Y)) Or ((PreviewWidth<PreviewHeight) And (100%X<100%Y)) Then
If True Then
PreviewScreenHeight=PreviewHeight
PreviewScreenWidth=PreviewWidth
Else
PreviewScreenHeight=PreviewWidth
PreviewScreenWidth=PreviewHeight
End If
Log(camEx.DispRotation)
For k=0 To myBitmap.Length-1
myBitmap(k).InitializeMutable( PreviewScreenWidth, PreviewScreenHeight )
myIV(k).Bitmap=myBitmap(k)
Next
' Original Java code
'mRgba = new Mat(height, width, CvType.CV_8UC4);
'mDetector = new ColorBlobDetector();
'mSpectrum = new Mat();
'mBlobColorRgba = new Scalar(255);
'mBlobColorHsv = new Scalar(255);
'SPECTRUM_SIZE = new Size(200, 64);
'CONTOUR_COLOR = new Scalar(255,0,0,255);
mYuvImage.Initialize2(3*PreviewHeight/2,PreviewWidth,mCvt.CV_8UC1)
mRgba.Initialize2(PreviewHeight,PreviewWidth,mCvt.CV_8UC4)
mDetector.Initialize
mBlobColorRgba.Set(Array As Double(255))
mBlobColorHsv.Set(Array As Double(255))
SPECTRUM_SIZE.Set(Array As Double(200,64))
CONTOUR_COLOR.Set(Array As Double(255,0,255,0))
ROTATED_CONTOUR_COLOR.Set(Array As Double(0,255,0,255))
Else
ToastMessageShow("Cannot open camera.", True)
End If
End Sub
Sub Button_Touch () ' I select de color directly..... mBlobColorHsv.Initialize3(121,216,181)
Dim x As Int=0
Dim y As Int=0
#if 0
//JAVA original code
int cols = mRgba.cols();
int rows = mRgba.rows();
int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;
int x = (int)event.getX() - xOffset;
int y = (int)event.getY() - yOffset;
Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
Rect touchedRect = new Rect();
touchedRect.x = (x>4) ? x-4 : 0;
touchedRect.y = (y>4) ? y-4 : 0;
touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
Mat touchedRegionRgba = mRgba.submat(touchedRect);
Mat touchedRegionHsv = new Mat();
Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
// Calculate average color of touched region
mBlobColorHsv = Core.sumElems(touchedRegionHsv);
int pointCount = touchedRect.width*touchedRect.height;
for (int i = 0; i < mBlobColorHsv.val.length; i++)
mBlobColorHsv.val[i] /= pointCount;
mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
mDetector.setHsvColor(mBlobColorHsv);
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE);
mIsColorSelected = true;
touchedRegionRgba.release();
touchedRegionHsv.release();
return false; // don't need subsequent touch events
#End If
Dim cols As Int = mRgba.cols()
Dim rows As Int = mRgba.rows()
Dim radius As Int = 20
Dim pointX As Int = X*PreviewWidth/myIV(0).Width
Dim pointY As Int = Y*PreviewHeight/myIV(0).Height
Dim touchedRegionRgba As OCVMat = mRgba.submat(pointY-radius,pointY+radius,pointX-radius,pointX+radius)'Y-10,Y+10,X-10,X+10)
Dim touchedRegionHsv As OCVMat
touchedRegionHsv.Initialize
mImgProc.cvtColor(touchedRegionRgba,touchedRegionHsv,mImgProc.COLOR_RGB2HSV_FULL,3)
Dim mCore As OCVCore
mBlobColorHsv = mCore.sumElems(touchedRegionHsv)
Dim pointCount As Int = 4*radius*radius
For i=0 To mBlobColorHsv.val.Length-1
mBlobColorHsv.val(i)=mBlobColorHsv.val(i)/pointCount
Next
mBlobColorHsv.Initialize3(121,216,181)
mBlobColorRgba = convertScalarHsv2Rgba(mBlobColorHsv) ' I select de color directly
mDetector.HsvColor=mBlobColorHsv
mSpectrum=mSpectrum.zeros(1,1,mCvt.CV_8UC1)
Dim mSpectrumTmp As OCVMat = mDetector.Spectrum
mImgProc.resize1(mSpectrumTmp,mSpectrum,SPECTRUM_SIZE)
mIsColorSelected=True
End Sub
Sub Timer11_Tick
PreviewBmp (BitmapToByte (CameraBmp.GetBitmapwh(640,480)))
End Sub
Sub BitmapToByte(Image As Bitmap) As Byte()
ToastMessageShow("BitmapToByt",False)
Dim out As OutputStream
Dim bb() As Byte
out.InitializeToBytesArray(0)
Image.WriteToStream(out,100,"JPEG")
out.Close
bb=out.ToBytesArray
Log(bb.Length)
Return bb
End Sub
Sub PreviewBmp (PreviewPic() As Byte)
'prevent queued events from previous camera settings, if any. Just in case
' If PreviewPic.Length<>(3*myBitmap(0).Width*myBitmap(0).Height/2) Then
' Log("Preview pic length is: "&PreviewPic.Length)
' Log("Bitmap size is: w="&myBitmap(0).Width&" h="&myBitmap(0).Height)
' Log("Not processing")
' Return
' End If
'Dim now As Long = DateTime.Now
'.....................................................
mYuvImage.put4(0,0,PreviewPic) ' I thin my problem is in this part the error is here
mImgProc.cvtColor(mYuvImage,mRgba,mImgProc.COLOR_YUV2RGBA_NV21,4)
'....................................................
If mIsColorSelected=False Then Return
mDetector.process(mRgba)
Dim contours As List = mDetector.Contours
'Log("Contours count: "&contours.Size)
Dim colorLabel As OCVMat = mRgba.submat(4,68,4,68)
colorLabel.setTo(mBlobColorRgba)
Dim spectrumLabel As OCVMat= mRgba.submat(4,4+mSpectrum.rows(),70,70+mSpectrum.cols())
mSpectrum.copyTo(spectrumLabel)
If contours.Size>0 Then
Dim mRect As OCVRect = mImgProc.boundingRect(contours.Get(0))
Dim mList As List
mList.Initialize2(Array(mRect))
mImgProc.rectangle(mRgba,mRect.tl,mRect.br,CONTOUR_COLOR,1dip,8,0)
Dim myContour0 As OCVMatOfPoint = contours.Get(0) 'OCVMatOfPoint2f in 3.20 version
Dim mType As OCVCvType
Dim myContour As OCVMatOfPoint2f 'OCVMatOfPoint2f in 3.20 version
myContour.Initialize
myContour0.convertTo2(myContour, mType.CV_32F)
Dim myContour2 As OCVMatOfPoint2f 'must be 2f or approxPolyDP complains
mImgProc.approxPolyDP(myContour,myContour2,0.1,True)
Dim myContour3 As OCVMatOfPoint
myContour3.Initialize3(myContour2.toArray)
Log(myContour2.toArray.Length)
Dim contour2List As List
contour2List.Initialize2(Array As OCVMatOfPoint(myContour3))
'contour2List.Add(myContour3)
mImgProc.drawContours2(mRgba,contour2List,0,CONTOUR_COLOR)
End If
'Log("Ellapsed: "& (DateTime.Now-now))
mUtils.matToBitmap(mRgba,myBitmap(0),False)
myIV(0).invalidate 'Refresh the view
End Sub
Private Sub convertScalarHsv2Rgba(hsvColor As OCVScalar) As OCVScalar
Dim pointMatRgba As OCVMat
pointMatRgba.Initialize
Dim pointMatHsv As OCVMat
pointMatHsv=pointMatHsv.zeros(1,1,mCvt.CV_8UC3)
pointMatHsv.setTo(hsvColor)
mImgProc.cvtColor(pointMatHsv,pointMatRgba, mImgProc.COLOR_HLS2RGB_FULL,4)
Dim retScalar As OCVScalar
Dim d() As Double=pointMatRgba.get5(0,0)
retScalar.Set(d)
Return retScalar
End Sub