I have an image on which gaussian blur is applied through this code
try {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat im = Imgcodecs.imread("bin\\" + backImage[randNum]);
Mat dst = new Mat();
Imgproc.GaussianBlur(im, dst, new Size(55, 55) ,8 , 8);
Imgcodecs.imwrite("bin\\gauLock.jpg", dst);
} catch (Exception e) {
dispose();
}
Now I want to unblur the area around the mouse cursor
Somewhat like this
So my questions are
Is this possible?
Can this be done using only opencv?
If yes then how?
Related
I'm trying to develop simple application (OpenCv, Tesseract and Java) where i need to get numbers from a photo of water meter. I am newbie to OpenCV and i am stuck on detection of numbers in rectangles.
So i want to achieve "00295" value as result.
Here is a example of water meter
But i am not able to achieve this result.
Steps:
Apply Gray filter
GaussianBlur filter 3x3
Sobel filter Threshold
And doing OCR with number characters allowed only
But in result i get bunch of random numbers from other labels.
Can you please give some suggestions and show way how to detect this 5 rectangles and get digits from them ?
Thanks in advance.
Here is code:
private static final int
CV_THRESH_OTSU = 8;
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat img = new Mat();
Mat imgGray = new Mat();
Mat imgGaussianBlur = new Mat();
Mat imgSobel = new Mat();
Mat imgThreshold = new Mat();
//Path to picture
String inputFilePath = "D:/OCR/test.jpg";
img = Imgcodecs.imread(inputFilePath);
Imgcodecs.imwrite("preprocess/1_True_Image.png", img);
Imgproc.cvtColor(img, imgGray, Imgproc.COLOR_BGR2GRAY);
Imgcodecs.imwrite("preprocess/2_imgGray.png", imgGray);
Imgproc.GaussianBlur(imgGray,imgGaussianBlur, new Size(3, 3),0);
Imgcodecs.imwrite("preprocess/3_imgGaussianBlur.png", imgGray);
Imgproc.Sobel(imgGaussianBlur, imgSobel, -1, 1, 0);
Imgcodecs.imwrite("preprocess/4_imgSobel.png", imgSobel);
Imgproc.threshold(imgSobel, imgThreshold, 0, 255, CV_THRESH_OTSU);
Imgcodecs.imwrite("preprocess/5_imgThreshold.png", imgThreshold);
File imageFile = new File("preprocess/5_imgThreshold.png");
Tesseract tesseract = new Tesseract();
//tessdata directory
tesseract.setDatapath("tessdata");
tesseract.setTessVariable("tessedit_char_whitelist", "0123456789");
try {
String result = tesseract.doOCR(imageFile);
System.out.println(result);
} catch (TesseractException e) {
System.err.println(e.getMessage());
}
}
}
If the position of the water filter won't change from image to image, could you just manually crop the image to your desired size? Also, after you blur the image, try using an adaptive threshold followed by canny edge detection. As a result, your image will only have the hard edges present. Then you could find contours on the image and filter through those contours till they fit the desired size that you want.
I am making a simple red color detector program using open cv but there is a problem with my JLabel it is not showing up the threshold image below is my code.
while(true)
{
try
{
cap.read(mat);// object of VideoCapture class
BufferedImage img= getImage(mat);// converts Mat to bufferedImage
lbl.setIcon(new ImageIcon(img));// this works fine
Mat hsv = new Mat();
Imgproc.cvtColor(mat, hsv, Imgproc.COLOR_BGR2HSV);// converts to hsv
Mat thresh = new Mat() ;
Core.inRange(hsv, new Scalar(0,100,100), new Scalar(10,255,255),thresh);
lbl2.setIcon(new ImageIcon(getImage(thresh)));// not showing up this
} catch(Exception e)
{}
}
Could anyone please tell what the issue is and how to solve it.Thanks.
This is the part of code which is not working good. I know this question has been asked earlier, but i have done everything i could do but still couldn't figure out the reason. This is the portion of code
Mat imgSource = original_image.clone();
// apply gaussian blur to smoothen lines of dots
Log.i(TAG, "Blur");
Imgproc.GaussianBlur(imgSource, imgSource, new Size(5, 5), 5);
// convert the image to black and white
Log.i(TAG, "B&W");
Log.i(TAG,Integer.toString(imgSource.type()));
Log.i(TAG,Integer.toString(imgSource.channels()));
Mat gray = new Mat(imgSource.size(),CvType.CV_8UC1);
Imgproc.cvtColor(imgSource, gray, Imgproc.COLOR_BGR2GRAY);
// convert the image to black and white does (8 bit)
Log.i(TAG, "Canny");
Imgproc.Canny(gray, gray, 50, 50);
// find the contours
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Log.i(TAG, "Contours");
Imgproc.findContours(gray, contours, new Mat(), Imgproc.RETR_LIST,
Imgproc.CHAIN_APPROX_SIMPLE);
Log.i(TAG,"Contours done");
//if no contours are detected
if(contours.size() == 0){
Log.i(TAG,"contour size is 0");
return gray;
}
In my Logcat i see the message "contour size is 0".
When i load the gray mat, i see a coloured image which explains why their were no contours detected.
Please suggest something.
Hello I think you may remove this row from your code:
Imgproc.Canny(gray, gray, 50, 50);
I'm using the Java bindings for OpenCv and attempting to add a border to an image that has been cropped. However, while the border draws 100% as expected on the full image, it doesn't draw the left side correctly if I crop the source image.
For example: Grumpy Cat
Now, to add the border, I've more or less copied the code from the OpenCV border tutorial.
e.g.
public class main {
public static void main( String[] args )
{
try{
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
Mat source = Highgui.imread("images\\original.jpg", Highgui.CV_LOAD_IMAGE_COLOR);
Mat destination = new Mat(source.rows(),source.cols(),source.type());
// make the border with a size of 10px for each side
Imgproc.copyMakeBorder(source, destination, 10, 10,
10, 10, Imgproc.BORDER_CONSTANT, new Scalar(255,0,0));
// Save the image
Highgui.imwrite("images\\borderWrap.jpg", destination);
}
catch (Exception e) {
System.out.println("error: " + e.getMessage());
}
}
}
Running this code, I get a nice border with 10px on each side as expected.
Now, If I modify the code to first crop the image, this stop working as expected.
public class main {
public static void main( String[] args )
{
try{
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
Mat isource = Highgui.imread("images\\original.jpg", Highgui.CV_LOAD_IMAGE_COLOR);
// crop the image to half of its width
Mat source = new Mat(isource, new Rect(0, 0, 480, 540));
Mat destination = new Mat(source.rows(),source.cols(),source.type());
// make the border with a size of 10px for each side
Imgproc.copyMakeBorder(source, destination, 10, 10,
10, 10, Imgproc.BORDER_CONSTANT, new Scalar(255,0,0));
// Save the image
Highgui.imwrite("images\\borderWrap.jpg", destination);
}
catch (Exception e) {
System.out.println("error: " + e.getMessage());
}
}
}
It doesn't draw the right side of the border. Is this a bug, or am I doing something wrong?
Now, If I do another call to copyMakeBorder, but this time with just the rightmost border param having a value it will fill it in correctly.
// First border pass (doesn't draw right size)
Imgproc.copyMakeBorder(source, destination, 10, 10,
10, 10, Imgproc.BORDER_CONSTANT,
new Scalar(255,0,0));
//Second border pass -- only rightmost param is supplied a size
Imgproc.copyMakeBorder(destination, destination, 0, 0,
0, 10, Imgproc.BORDER_CONSTANT,
new Scalar(255,0,0));
Anyone know what's going on here?
From Imgproc.copyMakeBorder javadoc:
When the source image is a part (ROI) of a bigger image, the function will try to use the pixels outside of the ROI to form a border. To disable this feature and always do extrapolation, as if src was not a ROI, use borderType BORDER_ISOLATED.
So if you switch to Imgproc.BORDER_ISOLATED constants it should work fine (and it does):
Imgproc.copyMakeBorder(source, destination, 10, 10, 10, 10,
Imgproc.BORDER_ISOLATED, new Scalar(255,0,0));
So I created an executable JAR using this code and everything works fine on my machine however I tested it on some other computers and the webcam capture never starts. The indicator light doesn't come on. This is the example I see in most tutorials for doing image capture and I'm doing face recognition so it's easiest to utilize the javaCV function rather than adding another library. All suggestions appreciated, thank you.
CanvasFrame canvas = new CanvasFrame("Webcam");
//Set Canvas frame to close on exit
canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
try {
//Start grabber to capture video
grabber.start();
//Declare img as IplImage
IplImage img;
long starttime = System.currentTimeMillis();
while (temptime < 4000) {
//inser grabed video fram to IplImage img
img = grabber.grab();
//Set canvas size as per dimentions of video frame.
canvas.setCanvasSize(grabber.getImageWidth(), grabber.getImageHeight());
if (img != null) {
//Flip image horizontally
cvFlip(img, img, 1);
//Draw text over the canvas
Graphics g = canvas.createGraphics();
g.setFont(camfont);
g.setColor(Color.red);
//Show video frame in canvas
canvas.showImage(img);
if (temptime > 2000 && tempcount == 1) {
//take and save the picture
cvSaveImage("User-cap.jpg", img);
tempcount++;
}
temptime = System.currentTimeMillis() - starttime;
}
}
} catch (Exception e) {
}
try {
grabber.stop();
canvas.dispose();
} catch (Exception e) {
System.out.println("Grabber couldn't close.");
}
you need to have OpenCV installed in the machine where you are running that program , jar only will contain javacv wrapper , but doesnt contains dll of opencv