Taking parts of one image to create another image - c++

I'm working with images from which I would like to take parts out and make one new image. I can make use of ImageMagick or OpenCV. Here is a sample image:
From this image I would like to take out the title, two annotated texts (one in circle one in rectangle), and the text from bottom.
So, the final image would have: Image Title, Annotated Text1, Annotated TExt, and This is some test. These parts of the image don't have to be in any particular order in the new image.
Questions
What kind of strategy can I use to do this?
Will hough or canny help?
I'm thinking that since the parts of the image I want back are all text, maybe hough line can detect the straight lines and then I crop out those parts of the images...
My main goal is to extract text so I can send it to an OCR
I've tried to erode the image and came up with this:
My Strategy
Following is my strategy to only keep parts of the image with white background and text. However, I'm not sure if this is doable with OpenCV...
There will be different ROI's in the image
there will always be white background on top of the image, lets call this space title. So I crop out the rectangle part on top of the image and save it as a separate image
there will always be white background at bottom of the image, lets call this body. So I crop out the rectangle part at bottom of the image and save it as a separate image
there will be some text on top of the image, lets call this annotated text. This will be in squares or circles. I can use technique mentioned in this answer to crop out those parts of the image and save them as a separate image.

If you are dealing with only similar looking fonts, and you are not looking for something super efficient, you can simply perform correlation with each letter of the alphabet (26 upper and 26 lower). Threshold out the peaks and add them together. You can then just define you bounding boxes around the peaks.

Related

Finding lines from text image OpenCV C++

I have images that are noised with some random lines like the following one:
I want to apply on them some preprocessing in order to find the lines (the lines that distort the writing).
I was seen some ways, but it is in Python, not C++:
Remove noisy lines from an image
Remove non straight lines from text image
In C++, I was try but result images:
the result which I want (I do it with Photoshop):
How to find lines in that images in C++ with OpenCV? thanks
I am not sure about this. Like #Chistoph Racwit said, you might need to use some sort of OCR.
But just to try it out, I think you can apply a horizontal filter that highlights any horizontal line in the image. It might not give the best-looking result but with some clean-up, you could end up with where the lines are in the image.
You can use this image to detect lines' locations and draw them in the original image with red color.

How to detect only the water or solution inside of the beaker in image. (OPENCV)

I am trying to find the region where it only has the solution/water in the beaker.
All images are converted into grayscale images and the other than a beaker and solution are all white pixels.
So one of the ideas was to find the vertical boundary and horizontal boundary to compute only the solution, and crop that region and saves it as a rectangle. but how to implement it would be my question.
I think the manual way is to start indexing from the middle point of images and try to find the non-white pixels.
Any suggestion?
Take a look at cv::watershed function that does image segmentation.
Here is also a tutorial that uses the function to isolate objects:
https://docs.opencv.org/3.0.0/d2/dbd/tutorial_distance_transform.html

How can I detect TV Screen from an Image with OpenCV or Another Library?

I've working on this some time now, and can't find a decent solution for this.
I use OpenCV for image processing and my workflow is something like this:
Took a picture of a tv.
Split image in to R, G, B planes - I'm starting to test using H, S, V too and seems a bit promising.
For each plane, threshold image for a range values in 0 to 255
Reduce noise, detect edges with canny, find the contours and approximate it.
Select contours that contains the center of the image (I can assume that the center of the image is inside the tv screen)
Use convexHull and HougLines to filter and refine invalid contours.
Select contours with certain area (area between 10%-90% of the image).
Keep only contours that have only 4 points.
But this is too slow (loop on each channel (RGB), then loop for the threshold, etc...) and is not good enought as it not detects many tv's.
My base code is the squares.cpp example of the OpenCV framework.
The main problems of TV Screen detection, are:
Images that are half dark and half bright or have many dark/bright items on screen.
Elements on the screen that have the same color of the tv frame.
Blurry tv edges (in some cases).
I also have searched many SO questions/answers on Rectangle detection, but all are about detecting a white page on a dark background or a fixed color object on a contrast background.
My final goal is to implement this on Android/iOS for near-real time tv screen detection. My code takes up to 4 seconds on a Galaxy Nexus.
Hope anyone could help . Thanks in advance!
Update 1: Just using canny and houghlines, does not work, because there can be many many lines, and selecting the correct ones can be very difficult. I think that some sort of "cleaning" on the image should be done first.
Update 2: This question is one of the most close to the problem, but for the tv screen, it didn't work.
Hopefully these points provide some insight:
1)
If you can properly segment the image via foreground and background, then you can easily set a bounding box around the foreground. Graph cuts are very powerful methods of segmenting images. It appears that OpenCV provides easy to use implementations for it. So, for example, you provide some brush strokes which cover "foreground" and "background" pixels, and your image is converted into a digraph which is sliced optimally to split the two. Here is a fun example:
http://docs.opencv.org/trunk/doc/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html
This is a quick something I put together to illustrate its effectiveness:
2)
If you decide to continue down the edge detection route, then consider using Mathematical Morphology to "clean up" the lines you detect before trying to fit a bounding box or contour around the object.
http://en.wikipedia.org/wiki/Mathematical_morphology
3)
You could train across a dataset containing TVs and use the viola jones algorithm for object detection. Traditionally it is used for face detection but you can adapt it for TVs given enough data. For example you could script downloading images of living rooms with TVs as your positive class and living rooms without TVs as your negative class.
http://en.wikipedia.org/wiki/Viola%E2%80%93Jones_object_detection_framework
http://docs.opencv.org/trunk/doc/py_tutorials/py_objdetect/py_face_detection/py_face_detection.html
4)
You could perform image registration using cross correlation, like this nice MATLAB example demonstrates:
http://www.mathworks.com/help/images/examples/registering-an-image-using-normalized-cross-correlation.html
As for your template TV image which would be slid across the search image, you could obtain a bunch of pictures of TVs and create "Eigenscreens" similar to how Eigenfaces are used for facial recognition and generate an average TV image:
http://jeremykun.com/2011/07/27/eigenfaces/
5)
It appears OpenCV has plenty of fun tools for describing shape and structure features, which appears to be mainly what you're interested in. Worth a look if you haven't seen this already:
http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html
Best of luck.

Extracting an object from a low contrast background

I need to extract an object from an image where the background is almost flat...
Consider for example a book over a big white desktop.. I need to get the coordinates of the 4 corners of the book to extract a ROI.
Which technique using OpenCV would you suggest? I was thinking to use k Means but I can't know the color of the background a priori (also the colors inside the object can be vary)
If your background is really low contrast, why not try a flood fill from the image borders, then you can obtain bounding box or bounding rect afterwards.
Another option is to apply Hough transform and take intersection of most outer lines as corners. This is, if your object is rectangular.

Extract Rectangle From Contour OpenCV

after making some edge and corner detection and then find contours i have this output.
how i can crop this image and return only this rectangle using openCV
EDIT:
i tried cvBoundingRect and then setimageROI but the output image still having some background but i want the rectangle only
Thank You.
i hope you need the rectangle area you selected.
For this you need to make another grayscale image, let us call it 'mask'. Then draw the rectangle contour obtained on it and fill it with white (255,255,255). You will obtain an image like this ( all images hand-edited in paint program):
Now just have an bitwise_and operation on both the images. You will get result as this:
**NB:**Now if it is not the one you wanted, instead you wanted this kind of selection, You can find information about it in this SOF question (thanks to karl philip for the link) .
I guess Mustafa wants to get the box automatically? If not, please accept Abid's answer and ignore this one.
Otherwise:
As I don't know how far it should generalize, for this specific image, do hough transform, which gives you straight lines. However the line at the bottom can become false positive. But with some post processing, e.g. blur, dilate, you will be able to get rid of it. Or you could use the knowledge that the lines build a rectangle.