Been trying to get inpainting to work on Android,
int height = (int) viewMat.size().height;
int width = (int) viewMat.size().width;
Mat maskMat = new Mat();
maskMat.create(viewMat.size(), CvType.CV_8U);
maskMat.setTo(bColor);
Point r1 = new Point(width/2-width/10, height/2-height/10);
Point r2 = new Point(width/2+width/10, height/2+height/10);
Scalar color = new Scalar(1);
Core.rectangle(maskMat, r1, r2, color, Core.FILLED);
outMat.create(viewMat.size(), CvType.CV_8UC3);
viewMat.convertTo(outMat, CvType.CV_8UC3);
Photo.inpaint(outMat, maskMat, outMat, 1, Photo.INPAINT_TELEA);
Was greeted with,
Caused by: CvException [org.opencv.core.CvException: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/photo/src/inpaint.cpp:744:
error: (-210) Only 8-bit 1-channel and 3-channel input/output images are supported in function void cvInpaint(const CvArr*, const CvArr*, CvArr*, double, int)
in logcat.
Been trying for hours creating Mats in various ways but to no valid.
CV_8U = 8 bit per channel, 1 channel. Right?
CV_8UC3 = 8 bit per channel, 3 channels. Right?
So what am I missing? I'm totally stumped.
...
Point r2 = new Point(width/2+width/10, height/2+height/10);
Scalar color = new Scalar(1);
Core.rectangle(maskMat, r1, r2, color, Core.FILLED);
Imgproc.cvtColor(viewMat, outMat, Imgproc.COLOR_RGBA2RGB);
Photo.inpaint(outMat, maskMat, outMat, 1, Photo.INPAINT_TELEA);
...
Turned out it was simply a matter of getting rid of the alpha channel via color conversion.
Image Inpaint Using OpenCv Android Studio
ImgMat = Mat()
Maskmat = Mat()
destmat=Mat()
Utils.bitmapToMat(BitmapImage, ImgMat)
Utils.bitmapToMat(BitmapMask, Maskmat)
Imgproc.cvtColor(ImgMat, ImgMat, Imgproc.COLOR_RGB2XYZ)
Imgproc.cvtColor(Maskmat, Maskmat, Imgproc.COLOR_BGR2GRAY)
Photo.inpaint(ImgMat,Maskmat,destmat, 15.0, INPAINT_NS)
InpaintBitmap= Bitmap.createBitmap(BitmapImage.getWidth(),
BitmapImage.getHeight(),
Bitmap.Config.ARGB_8888)
Imgproc.cvtColor(destmat, destmat, Imgproc.COLOR_XYZ2RGB);
Utils.matToBitmap(destmat, InpaintBitmap)
Description:
InpaintBitmap is an Inpaint color Bitmap
src image is a 3 channel image but mask bitmap is a 1 channel image
Related
In OpenCV android, is it possible to apply bilateral filtering? I know that I can do gaussian blurring like Imgproc.GaussianBlur(gray, gray, new Size(15,15), 0); but I cannot seem to find the code for bilateral filtering.
Seems it's possible like:
Imgproc.bilateralFilter(mat, dstMat, 10, 50, 0);
from here and here.
Update
This:
E/AndroidRuntime: FATAL EXCEPTION: Thread-1376 Process: PID: 30368 CvException [org.opencv.core.CvException: cv::Exception: /Volumes/build-storage/build/2_4_pack-android/opencv/modules/imgproc/src/smooth.cpp:1925: error: (-215) (src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data in function void cv::bilateralFilter_8u(const cv::Mat&, cv::Mat&, int, double, double, int)
is because wrong color format of processing Mat. You should convert 4 channels RGBA format to 3 channels RGB for bilateralFilter() apply (like in bilateralFilterTutorial() method here). So, You code should be like that:
// load Mat from somewhere (e.g. from assets)
mSourceImageMat = Utils.loadResource(this, R.drawable.<your_image>);
// convert 4 channel Mat to 3 channel Mat
Imgproc.cvtColor(mSourceImageMat, mSourceImageMat, Imgproc.COLOR_BGRA2BGR);
// create dest Mat
Mat dstMat = mSourceImageMat.clone();
// apply bilateral filter
Imgproc.bilateralFilter(mSourceImageMat, dstMat, 10, 250, 50);
// convert to 4 channels Mat back
Imgproc.cvtColor(dstMat, dstMat, Imgproc.COLOR_RGB2RGBA);
// create result bitmap and convert Mat to it
Bitmap bm = Bitmap.createBitmap(mSourceImageMat.cols(), mSourceImageMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, bm);
// show bitmap on ImageView
mImageView.setImageBitmap(bm);
The problem could be, that you use PNG image, which has a 4th channel for transparency. Convert it from 4 channel to 3 channel, before use.
Imgproc.cvtColor(src,dst,Imgproc.COLOR_BGRA2BGR);
I am trying to use K-means JavaCV implementation, but I have the following error:
OpenCV Error: Assertion failed (!centers.empty()) in cvKMeans2, file src\matrix.cpp, line 4233
My source code is:
IplImage src = cvLoadImage(fileName, CV_LOAD_IMAGE_COLOR);
int cluster_count = 3;
int attempts = 10;
CvTermCriteria termCriteria = new CvTermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER, 10, 1.0);
cvReshape(src, src.asCvMat(), 1, src.height() * src.width());
IplImage samples = cvCreateImage(cvGetSize(src), src.depth(), 1);
cvConvertImage(src, samples, CV_32F);
IplImage labels = cvCreateImage(new CvSize(samples.height()), 1, CV_8U);
IplImage centers = cvCreateImage(new CvSize(cluster_count), 1, CV_32F);
cvKMeans2(samples, cluster_count, labels, termCriteria, 1, new long[attempts], KMEANS_RANDOM_CENTERS, centers, new double[attempts]);
I'm beginner on JavaCV and would to know what I doing wrong in this code?
I'm new to opencv's svm's. I tried a sample classifier but it only returns 0 as the predicted label. I even used the value 5 for training as well as the prediction.
I've been changing the values for about a hundred times but i just don't get what's wrong. I'm using OpenCV 3.0 with Java. Here's my code:
Mat labels = new Mat(new Size(1,4),CvType.CV_32SC1);
labels.put(0, 0, 1);
labels.put(1, 0, 1);
labels.put(2, 0, 1);
labels.put(3, 0, 0);
Mat data = new Mat(new Size(1,4),CvType.CV_32FC1);
data.put(0, 0, 5);
data.put(1, 0, 2);
data.put(2, 0, 3);
data.put(3, 0, 8);
Mat testSamples = new Mat(new Size(1,1),CvType.CV_32FC1);
testSamples.put(0,0,5);
SVM svm = SVM.create();
TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER,100,0.1);
svm.setKernel(SVM.LINEAR);
svm.setType(SVM.C_SVC);
svm.setGamma(0.5);
svm.setNu(0.5);
svm.setC(1);
svm.setTermCriteria(criteria);
//data is N x 64 trained data Mat , labels is N x 1 label Mat with integer values;
svm.train(data, Ml.ROW_SAMPLE, labels);
Mat results = new Mat();
int predictedClass = (int) svm.predict(testSamples, results, 0);
Even if i change the lables to 1 and 2, I still get 0.0 as a response. So something has to be absolutely wrong... I just don't know what to do. Please help! :)
I had a similar problem in C++. I'm not too sure if it's the same in Java but in C++ the predictions were saved in the results Matrix instead of returned as a float.
After decoding an image this way Iam passing it to a read file
Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, 5, 5, bitmap.getWidth() - 10, bitmap.getHeight() - 10,matrix,true);
System.out.println("The new cropped bitmap>>>>>>>>>>>>>" + croppedBitmap.getWidth() + "<<<>>>>" +croppedBitmap.getHeight());
this.bmp = croppedBitmap;
Readfile.readBitmap(bitmap)
Now I am processing and binarizing an image this way.
Pix var2 = Binarize.otsuAdaptiveThreshold(var1);
var2 = Rotate.rotate(AdaptiveMap.backgroundNormMorph(Convert.convertTo8(var1), 8, 6, 250), Skew.findSkew(var2));
The above algorithm does a good job on the background service and produces the result but my present challenge is that it takes such a long time (40 seconds) to process the image. So my intention is to process and binarize the image at 10 seconds that made me arrive by the approach above, so am asking is there a way I can decrease the processing time to about 10 seconds.
Thanks!
As described in post title, I'm looking for a way to detect motion/movement on the input stream from CCTV camera (IP/WiFi). Anyone know best way how I can connect to IP video stream and monitor for motion?
this is the opencv code in python, java is simiar, you need use opencv for the image operation
import cv2, time, pandas
from datetime import datetime
first_frame = None
status_list = [None,None]
times = []
df=pandas.DataFrame(columns=["Start","End"])
video = cv2.VideoCapture('rtsp://admin:Paxton10#10.199.27.128:554')
while True:
check, frame = video.read()
status = 0
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(21,21),0)
if first_frame is None:
first_frame=gray
continue
delta_frame=cv2.absdiff(first_frame,gray)
thresh_frame=cv2.threshold(delta_frame, 30, 255, cv2.THRESH_BINARY)[1]
thresh_frame=cv2.dilate(thresh_frame, None, iterations=2)
(cnts,_)=cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in cnts:
if cv2.contourArea(contour) < 200000:
continue
status=1
(x, y, w, h)=cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 3)
status_list.append(status)
status_list=status_list[-2:]
if status_list[-1]==1 and status_list[-2]==0:
times.append(datetime.now())
if status_list[-1]==0 and status_list[-2]==1:
times.append(datetime.now())
#cv2.imshow("Gray Frame",gray)
#cv2.imshow("Delta Frame",delta_frame)
imS = cv2.resize(thresh_frame, (640, 480))
cv2.imshow("Threshold Frame",imS)
imS = cv2.resize(frame, (640, 480))
cv2.imshow("Color Frame",imS)
#cv2.imshow("Color Frame",frame)
key=cv2.waitKey(1)
if key == ord('q'):
if status == 1:
times.append(datetime.now())
break
print(status_list)
print(times)
for i in range(0, len(times), 2):
df = df.append({"Start": times[i],"End": times[i+1]}, ignore_index=True)
df.to_csv("Times.csv")
video.release()
cv2.destroyAllWindows