I'm trying to create app for applying Affine transform only for some part of image(non rectangular).
http://s29.postimg.org/k45fwbmsn/Untitled.png
Is there exist any way, to transform only selected(visible) part of the image?
I'm certain the overall transformation you described (only on part of an image) is not affine. So it isn't as easy as applying a matrix multiplication to some vectors.
But of course, there are ways to define algorithms that detect black rectangles and apply an affine transformation to the coordinates of detected rectangles. With the transformed coordinates you can draw a new quadrangle. Note: After an affine transformation it does not need to be a rectangle anymore.
Btw. you're contradicting yourself:
transform only for some part of image(non rectangular).
vs
to transform only black rectangle
I'd propose you clarify the following points about your input and expected output:
Which of the contradicting transformations do you want: Only rectangles or everything but rectangles?
Is it binary black-and-white, gray-level or colour image? This is a question of simple to complex input with quite some impact on the algorithm.
Is the image noiseless, i.e. is it true black or all sorts of really dark colours? For true black you might be able to apply a simple heuristic to detect the rectangles. If it's a noisy image you need to think about image filters/improvements and colour space transitions.
Are the rectangles the only "black" areas in your image?
Are the rectangles in parallel to x and y axis? Again this is simple heuristic vs pattern recognition.
Is the number of rectangles known? Are multiple rectangles related (in size, proportions, parallel) to each other?
What is to happen on borders or with image parts revealed by moving/shrinking the rectangles?
I'll edit the answer, when you provide the required information in your question.
Related
For a project, I need to store circles detected on some photos. The problem is that some of these photos are taken from an angle, meaning the circles are ellipses. Is it possible to somehow turn the ellipses into circles?
I thought of rectifying the ellipse, then transforming the rectangle to a square. Indeterminate problem comes to my mind, meaning there are too many possible variations for my approach, and the results are different for each approach.
To find perspective transform, you need to have 4 pairs of corresponding coordinates: points at distorted picture and their ideal positions after correction of perspective.
In this case you can calculate matrix of perspective transform with getPerspectiveTransform function and apply it to correct all the picture. Example
What is Distance Transform?What is the theory behind it?if I have 2 similar images but in different positions, how does distance transform help in overlapping them?The results that distance transform function produce are like divided in the middle-is it to find the center of one image so that the other is overlapped just half way?I have looked into the documentation of opencv but it's still not clear.
Look at the picture below (you may want to increase you monitor brightness to see it better). The pictures shows the distance from the red contour depicted with pixel intensities, so in the middle of the image where the distance is maximum the intensities are highest. This is a manifestation of the distance transform. Here is an immediate application - a green shape is a so-called active contour or snake that moves according to the gradient of distances from the contour (and also follows some other constraints) curls around the red outline. Thus one application of distance transform is shape processing.
Another application is text recognition - one of the powerful cues for text is a stable width of a stroke. The distance transform run on segmented text can confirm this. A corresponding method is called stroke width transform (SWT)
As for aligning two rotated shapes, I am not sure how you can use DT. You can find a center of a shape to rotate the shape but you can also rotate it about any point as well. The difference will be just in translation which is irrelevant if you run matchTemplate to match them in correct orientation.
Perhaps if you upload your images it will be more clear what to do. In general you can match them as a whole or by features (which is more robust to various deformations or perspective distortions) or even using outlines/silhouettes if they there are only a few features. Finally you can figure out the orientation of your object (if it has a dominant orientation) by running PCA or fitting an ellipse (as rotated rectangle).
cv::RotatedRect rect = cv::fitEllipse(points2D);
float angle_to_rotate = rect.angle;
The distance transform is an operation that works on a single binary image that fundamentally seeks to measure a value from every empty point (zero pixel) to the nearest boundary point (non-zero pixel).
An example is provided here and here.
The measurement can be based on various definitions, calculated discretely or precisely: e.g. Euclidean, Manhattan, or Chessboard. Indeed, the parameters in the OpenCV implementation allow some of these, and control their accuracy via the mask size.
The function can return the output measurement image (floating point) - as well as a labelled connected components image (a Voronoi diagram). There is an example of it in operation here.
I see from another question you have asked recently you are looking to register two images together. I don't think the distance transform is really what you are looking for here. If you are looking to align a set of points I would instead suggest you look at techniques like Procrustes, Iterative Closest Point, or Ransac.
I'm new to image processing and I'm working on detecting lines in a document image. I read the theory of Hough line transform but I can't see why I must use Canny before calling that function in opencv like being said in many tutorials. What's the point of finding edges in this case? The fact is that if I don't use Canny or threshold before HoughLines() the results will be very messy. I hope someone will explain for me the reason why.
2 of the tutorials I've read:
Imgproc Feature Detection
Hough Line Transform
Short Answer
cvCanny is used to detect Edges, as well as increase contrast and remove image noise.
HoughLines which uses the Hough Transform is used to determine whether those edges are lines or not. Hough Transform requires edges to be detected well in order to be efficient and provide meaning results.
Long Answer
The Limitations of the Hough Transform are described in more detail on Wikipedia.
The efficiency of the Hough Transform relies of the bin of acculumated pixel being distinct, e.g. a direct contrast between a pixel and its surrounding neighbours or if using a mask region a pixel region and its surrounds regions. If all pixels had similar acculumated values nothing would stand out as a line or circle. This leads to the reduction of colour (colour to grayscale, grayscale to black and white) in order to increase contract.
The number of parameters to the Hough Transform also increase the spread of votes in the pixel bins and increase the complexity of the transform, which mean that normally only lines or circles are reliably detected using it as they have less than 3 parameters.
The edges need to be detected well before running the Hough Transform otherwise its efficiency suffers further. Also noisy images don't work well with Hough transform unless the noise is removed before hand.
First of all, to detect lines you need to work on a boolean matrix image (or binary), I mean: the color is black or white, there's no grayscale.
HoughLines()'s requirement to work properly is to have this kind of image as input. That's the reason you have to use Canny or Treshold, to convert the colored image matrix into a boolean one.
Hough transformation
A line in one picture is actually an edge. Hough transform scans the whole image and using a transformation that converts all white pixel cartesian coordinates in polar coordinates; the black pixels are left out. So you won't be able to get a line if you first don't detect edges, because HoughLines() don't know how to behave when there's a grayscale.
Theoretically, you are correct. Finding edges is not absolutely required for the Hough Line algorithm to work.
The way the Hough works is basically it takes every point and connects it to every other point, and whatever points have the most lines going through them, those lines stay. For this, we need points. The Canny creates those points. Theoretically you could use any sort of filter - isolate all blue or purple points and connect them, whatever - but edges works well.
The Hough also does not weight its lines or points. To the Hough, an image is binary - made up of either 1s or 0, points or not points. There is no need for greyscale, and the canny conveniently returns binary images.
Thus is the Canny always part of the Hough.
all is about processing binary data,
complex data -> (a binary data, b binary data, c binary data, ..) (using canny(),sobel(), etc)
a binary data -> function1() (using houghlines())
b binary data -> function2()
c binary data -> function3() ..
a binary data -X-> function2() ..
complex data -X-> function1() ..
HTH
The application PhotoFiltre has an option to stretch part of an image. You select a rectangular shape and you can then grab and move the vertexes somewhere else to make any quadrangle. The image part which you selected will stretch along. Hopefully these images make my point a little clearer:
Is there a general algorithm which can handle this? I would like to obtain the same effect on HTML5 canvas - given an image and the resulting corner points, I would like to be able to draw the stretched image in such a way that it fills the new quadrangle neatly.
A while ago I asked something similar, where the solution was to divide the image up in triangles and stretch each triangle so that each three points correspond to the three points on the original image. This technique turned out to be rather exprensive and I would like if there is a more general method of accomplishing this.
I would like to use this in a 3D renderer, but I would like to work with a (2D) quadrangle.
I don't know whether PhotoFiltre internally also uses triangles, or whether it uses another (cheaper) algorithm to stretch an image like this.
Does someone perhaps know if there is a cheaper or more general method/algorithm to stretch a rectangular image, so that it fills a quadrangle given four points?
The normal method is to start with the destination, pick an appropriate grid size and then for each point in the new shape calculate the corresponding point in the source image (possibly with interpolation depending on the quality you need)
Affine transform.
Given four points for the "stretched" figure and four points for the figure it should match (e.g. a rectangle), an affine transform provides the spatial mapping you need. For each point (x1,y1) in the original image there is a corresponding point (x2,y2) in the second, "stretched" image.
For each integer-valued pixel (x2, y2) in the stretched image, use the affine transform to find the corresponding real-valued point (x1, y1) in the original image and apply its color to (x2,y2).
http://demonstrations.wolfram.com/AffineTransform/
You'll find sample code for Java and other languages online. .NET has the Matrix class.
I have several binary images and my task is to segment circle-like shape. The circles are not perfect rounded circle, but all of them will look like circle. Here are some example images and what I need:
As you can see from above, the left images are original images, and the right images are what I need to do. The circles intersect with other shapes, but I only want the circle, as indicated in red. The imaginary lines to close the circle will be required. What can I do in this case in Image Processing?
EDIT: in case, the image above is broken, here: http://imageshack.us/photo/my-images/835/circleonly.jpg/
Do you know the radii of the disks you are looking for?
If yes, morphological openings (erosion then dilation) would be straightforward, and very fast. The result using Mathematica:
Opening[img, DiskMatrix[15]]
If not, as other proposed, computing the contour image and then using the Hough transform would be a method worth pursuing. The image just above shows the contour image.
You can use hough transform, first you need is the edge image then you use a hough transform like you can see in this papers
http://www.cis.rit.edu/class/simg782/lectures/lecture_10/lec782_05_10.pdf
http://www.sci.utah.edu/~gerig/CS6640-F2010/FINALPROJECT/Ballard-GHT-1981.pdf
http://www.sciencedirect.com/science/article/pii/003132039290064P
http://www.markschulze.net/java/hough/