I am trying to change the hue of image store in matrix. I got a hue channel using split() function but i am not able to change its hue. I am using the function set(Scalar scalar) to change its hue, but i don't see any change in image.
Mat eyeball_HSV = new Mat();
Mat dest = new Mat();
Mat eye = new Mat();
eye = mRgba.submat(eye_template);
List<Mat> hsv_channel = new ArrayList<Mat>();
Imgproc.cvtColor(eye, eyeball_HSV, Imgproc.COLOR_RGB2HSV, 0);
// get HSV channel
//hsv_channel[0] is hue
//hsv_channel[1] is saturation
//hsv_channel[2] is visibility
Core.split(eyeball_HSV, hsv_channel);
try
{
hsv_channel.get(0).setTo(new Scalar(145,25,45));
Log.v(TAG, "Got the Channel!");
}
catch(Exception ex)
{
ex.printStackTrace();
Log.v(TAG, "Didn't get any channel");
}
Imgproc.cvtColor(eyeball_HSV, dest, Imgproc.COLOR_HSV2RGB);
Imgproc.cvtColor(dest, eye, Imgproc.COLOR_RGB2RGBA);
Just change the code
hsv_channel.get(0).setTo(new Scalar(145,25,45));
to
hsv_channel.get(0).setTo(new Scalar(145)); // whatever your value
hsv_channel.get(0) is single channel Mat so your Scalar value should be with single.
Edit:-
Yo can see the OpenCV camera preview example here
On Tutorial1Activity.java you can see a method
public Mat onCameraFrame(CvCameraViewFrame inputFrame)
Add these lines on this method
src = inputFrame.rgba();
Imgproc.cvtColor(src, hsv,Imgproc.COLOR_RGB2HSV );
Core.split(hsv, hsv_channel);
// Imgproc.equalizeHist(hsv_channel.get(0), hsv_channel.get(0));
hsv_channel.get(0).setTo(new Scalar(64));
Core.merge(hsv_channel, hsv);
Imgproc.cvtColor(hsv, src,Imgproc.COLOR_HSV2RGB );
//return hsv_channel.get(0);
return src;
Related
So I have been trying to get coordinates of the corner in a QR 1.
But the output from detectAndDecode functions return some string that looks like "[D#fb258ec".
What have I done wrong? Or is the vertices not meant what I think they mean?
Just starting out on the journey to learn openCV and Android, the process has been though...
Any help or advice is much appreciated, thanks.
A snippet of what I think is the main part is shown below.
Edit 1: Added link to QR and more code.
#Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
mat1 = inputFrame.gray();
Mat clrCrr = new Mat();
Imgproc.cvtColor(mat1, clrCrr, Imgproc.COLOR_GRAY2BGR);
QRCodeDetector decoder = new QRCodeDetector();
Mat QR = new Mat(); //Mat for QR code
Mat points = new Mat(); // points of QR Mat
Mat dst = new Mat(); //Output frame
runOnUiThread(new Runnable() {
public void run() {
Handler h = new Handler();
String data = decoder.detectAndDecode(clrCrr, points,QR); //Decode QR
EditText editText = findViewById(R.id.editText);
points.convertTo(points,CvType.CV_64FC3);
editText.setText("Point 1 " +points.get(0,0) );
Log.d("Test", String.valueOf(points.get(0,1)));
h.postDelayed(this,3000);
}
});
Imgproc.threshold(mat1, dst, 100, 200, Imgproc.THRESH_BINARY); // Threshold and return dst
return dst
}
I think I found the solution.
Just need to use
Arrays.toString(points.get(0,0))
instead of just
points.get(0,0)
This will then return a coordinates like [1142.0, 230.0]
I am trying to detect laser light dot of any colour of laser.and i have done some reference code from here OpenCV Android Track laser dot
That code is running perfectly for Only RED colour detection and i want any colour of laser dot detection.
I am new in OpenCV.
Here's what i have done till now :
Mat originalFrame= new Mat();
Mat frame = new Mat();
cvf.rgba().copyTo(originalFrame);
cvf.rgba().copyTo(frame);
Mat frameH;
Mat frameV;
Mat frameS;
mRgba = cvf.rgba();
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
// Mat frameS;
// Convert it to HSV
Imgproc.cvtColor(frame, frame, Imgproc.COLOR_RGB2HSV);
// Split the frame into individual components (separate images for H, S,
// and V)
mChannels.clear();
Core.split(frame, mChannels); // Split channels: 0-H, 1-S, 2-V
frameH = mChannels.get(0);
frameS = mChannels.get(1);
frameV = mChannels.get(2);
// Apply a threshold to each component
Imgproc.threshold(frameH, frameH, 155, 160, Imgproc.THRESH_BINARY);
// Imgproc.threshold(frameS, frameS, 0, 100, Imgproc.THRESH_BINARY);
Imgproc.threshold(frameV, frameV, 250, 256, Imgproc.THRESH_BINARY);
// Perform an AND operation
Core.bitwise_and(frameH, frameV, frame);
//
// Core.bitwise_and(frame,frameS,frame);
Imgproc.findContours(frame, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
hierarchy.release();
for ( int contourIdx=0; contourIdx < contours.size(); contourIdx++ )
{
// Minimum size allowed for consideration
MatOfPoint2f approxCurve = new MatOfPoint2f();
MatOfPoint2f contour2f = new MatOfPoint2f( contours.get(contourIdx).toArray() );
//Processing on mMOP2f1 which is in type MatOfPoint2f
double approxDistance = Imgproc.arcLength(contour2f, true)*0.02;
Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);
//Convert back to MatOfPoint
MatOfPoint points = new MatOfPoint( approxCurve.toArray() );
// Get bounding rect of contour
Rect rect = Imgproc.boundingRect(points);
Imgproc.rectangle(originalFrame, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 0, 255), 3);
}
This is old question but i have findy my solution using core.InRange
Follow my alternative version
#Override
public void onCameraViewStarted(int width, int height) {
mat1 = new Mat(height, width, CvType.CV_16UC4);
mat2 = new Mat(height, width, CvType.CV_16UC4);
}
#Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat src = inputFrame.rgba();
Imgproc.cvtColor(inputFrame.rgba(), mat1, Imgproc.COLOR_BGR2HSV);
//rangeLow and RangeHight is Scalar
Core.inRange(mat1, rangeLow, rangeHight, mat2);
Core.MinMaxLocResult mmG = Core.minMaxLoc(mat2);
Core.rotate(src, src, Core.ROTATE_90_CLOCKWISE);
Imgproc.circle(src,mmG.maxLoc,30,new Scalar(0,255,0), 5, Imgproc.LINE_AA);
return src;
}
The code you posted carries out two thresholding operations. One on the hue and one on the value. It then ANDs the results together. Because of the way it thresholds the hue, the effect is that it is looking for a bright red(ish) spot.
My first solution would be to look for just a bright spot (so just look on the hue frame). You might also try looking for high saturations (except that a laser spot may well overload the sensors, and result in an apparently unsaturated pixel).
To select the appropriate threshold values, you will have to experiment with various images.
Using OpenCV4Android, how can I get the HSV channels of the first pixel of the masked region in a masked image (dilatedMat in the following snippet)? I know that we'd get the HSV channel values of first pixel by hsvMat.get(0,0) but I don't know how to apply this to the masked region only, rather than the entire Mat.
For example, following is a function to which a camera frame is passed as an argument, and I have generated a mask, but how should I proceed from there?
NOTE: Please keep in mind that the masked region is Not a rectangle, it has an irregular shape.
private void detectColoredBlob (Mat rgbaFrame) {
Mat hsvImage = new Mat();
Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_RGB2HSV_FULL);
Mat maskedImage = new Mat();
Scalar lowerThreshold = new Scalar(85, 50, 20);
Scalar upperThreshold = new Scalar(135, 255, 77);
Core.inRange(hsvImage, lowerThreshold, upperThreshold, maskedImage);
Mat dilatedMat= new Mat();
Imgproc.dilate(maskedImage, dilatedMat, new Mat() );
//****************WHAT NOW???**************
}
i have started working on opencv on android platform. I wanted to change the hue of image, not the whole just the sub part of it.
So how we do that
Change full image to hsv
then select that specific part (Matrix)
and change it's hue
then convert the image back to rgba (i am working on android so it
should b 4 channel. am i right??)
Or
Select that sub part (Matrix)
Change that sub part to hsv
Change it's hue
Convet back that specific part back to rgba
I have also try some code using second method i am not succeed yet. So i want some good examples or some guidance how to acheive that.
You can use OpenCV camera preview example from sample folder
Try below code
//Global variable
private Mat src;
Mat hsv = null;
private CameraBridgeViewBase mOpenCvCameraView;
List<Mat> hsv_channel= new ArrayList<Mat>();
---------------------------------------
----------------------------------------
// Initialize Mat here
public void onCameraViewStarted(int width, int height) {
src = new Mat(height, width, CvType.CV_8UC4);
hsv = new Mat(height, width, CvType.CV_8UC4);
}
-----------------------------------------
---------------------------------------
//Process Mat here
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
src = inputFrame.rgba();
Imgproc.cvtColor(src, hsv,Imgproc.COLOR_BGR2HSV );
Core.split(hsv, hsv_channel);
Imgproc.equalizeHist(hsv_channel.get(0), hsv_channel.get(0)); //Get hue channel and perform hsitogram equlization
Core.merge(hsv_channel, hsv);
Imgproc.cvtColor(hsv, src,Imgproc.COLOR_HSV2BGR );
return src;
}
i am working on opencv in android. actually i am doing eye detection in opencv and want to change the color of eyes in real time. For Example: through front camera eye pupil is detcted and change the pupil color. i have problem in geting Hue channel. Kindly help
Mat eyeball_HSV = new Mat();
Mat dest = new Mat();
Mat eye = new Mat();
eye = mRgba.submat(eye_template).clone();
List<Mat> hsv_channel = new ArrayList<Mat>();
//convert image to HSV
// Imgproc.cvtColor(eye, eyeball_RGB, Imgproc.COLOR_RGBA2RGB, 3);
Imgproc.cvtColor(eye, eyeball_HSV, Imgproc.COLOR_RGB2HSV, 0);
//Core.inRange(eyeball_HSV, new Scalar(90, 50, 50), new Scalar(130, 255, 255), dest);
// get HSV channel
//hsv_channel[0] is hue
//hsv_channel[1] is saturation
//hsv_channel[2] is visibility
Core.split(eyeball_HSV, hsv_channel);
try
{
hsv_channel.get(0).setTo(new Scalar(145));
Log.v(TAG, "Got the Channel!");
}
catch(Exception ex)
{
ex.printStackTrace();
Log.v(TAG, "Didn't get any channel");
}
Imgproc.cvtColor(eyeball_HSV, dest, Imgproc.COLOR_HSV2RGB);
Imgproc.cvtColor(dest, eye, Imgproc.COLOR_RGB2RGBA);