I need a counter-clockwise deskew of 5 degrees on a jpg image. I want to do this with the program convert of the ImageMagick tool suite. I thus need a command like:
convert '2 skewed jpg/p. 2.jpg' -deskew ???% '3 deskewed jpg/p. 2.jpg'
The question is what value should be filled in for ????
I tried already many things, and nothing works.
In ImageMagick, -deskew is an automatic process to square up the image. It typically works for skewed images of about 5 deg or less. You can try 40% as a start and increase if it does not work.
But I think you want -shear, which does a controlled skew or shear with degree argument values. See https://www.imagemagick.org/script/command-line-options.php#shear. For a horizontal shear top left by 5 deg, try
convert input.jpg -background white -shear -5x0 result.jpg
Input:
convert lena.jpg -background white -shear -5x0 result.jpg
enter image description here
My goal is to take the image above and "open" it along the center so that the 9 black doublets are in a straight line rather than in a circle. I have tried using the cv2.toPolar() function in OpenCV but the image is quite distorted, as can be seen below:
enter image description here
I am attempting to try a different approach now. From the center, I would like to access each of the doublet individually, like a pizza slice, and place them side by side
Initially I was thinking of slicing each doublet using two lines from the center of the image to the mid point between the doublets on either side.
My question is: how can I draw contours from the center of the image to the edge of the image, passing through the mid point between any two doublet. If I can draw one, I know that the angle between any two such consecutive contour is 40 degrees.
Any help is greatly appreciated!
I noted a few problems here:
The toPolar() conversion might have been around the center of the image file, but it is not the center of the object. This causes part of the distortion. If you share your code, I could try playing with the code and improving it.
2.The object is somewhat elliptical, not circular. This means you will still have a wave after correcting the above problem.
If you don't mind a semi-automatic solution, you could use OpenCV mouse events to specify the first line and let the program use the 40 degree angle to calculate the rest.
I need to be able to turn a black and white image into series of lines (start, end points) and circles (start point, radius). I have a "pen width" that's constant.
(I'm working with a screen that can only work with this kind of graphics).
Problem is, I don't want to over complicate things - I could represent any image with loads of small lines, but it would take a lot of time to draw, so I basically want to "approximate" the image using those lines and circles.
I've tried several approaches (guessing lines, working area by area, etc) but none had any reasonable results without using a lot of lines and circles.
Any idea on how to approach this problem?
Thanks in advance!
You don't specify what language you are working in here but I'd suggest OpenCV if possible. If not, then most decent CV libraries ought to support the features that I'm about to describe here.
You don't say if the input is already composed of simple shapes ( lines and polygons) or not. Assuming that it's not, i.e. it's a photo or frame from a video for example, you'll need to do some edge extraction to find the lines that you are going to model. Use a Canny or other edge detector to convert the image into a series of lines.
I suggest that you then extract Circles as they are the richest feature that you can model directly. You should consider using a Hough Circle transform to locate circles in your edge image. Once you've located them you need to remove them from the edge image (to avoid duplicating them in the line processing section below).
Now, for each pixel in the edge image that's 'on' you want to find the longest line segment that it's a part of. There are a number of algorithms for doing this, simplest would be Probabilistic Hough Transform (also available in openCV) to extract line segments which will give you control over the minimum length, allowed gaps etc. You may also want to examine alternatives like LSWMS which has OpenCV source code freely available.
Once you have extracted the lines and circles you can plot them into a new image or save the coordinates for your output device.
From a large collection of jpeg images, I want to identify those more likely to be simple logos or text (as opposed to camera pictures). One identifying characteristic would be low color count. I expect most to have been created with a drawing program.
If a jpeg image has a palette, it's simple to get a color count. But I expect most files to be 24-bit color images. There's no restriction on image size.
I suppose I could create an array of 2^24 (16M) integers, iterate through every pixel and inc the count for that 24-bit color. Yuck. Then I would count the non-zero entries. But if the jpeg compression messes with the original colors I could end up counting a lot of unique pixels, which might be hard to distinguish from a photo. (Maybe I could convert each pixel to YUV colorspace, and save fewer counts.)
Any better ideas? Library suggestions? Humorous condescensions?
Sample 10000 random coordinates and make a histogram, then analyze the histogram.
I have a image with horizontal and vertical lines. In fact, this image is the BBC website converted to horizontal and vertical lines.
My problem is that I want to be able to find all the rectangles in the image. I want to write a computer program to find all the rectangles.
Does anyone know how to do this or suggest ideas on how to get started? This task is easy for me as a person to find the visual rectangles, but I am not sure how to describe it as a program.
Image is the BBC website here http://www.bbc.co.uk/
Update to this, I wrote the code which converts the BBC website image to the horizontal and vertical line, the problem is these lines do not completely meet at the corners and sometimes they do not completely form a rectangle. Thanks!
Opencv (image processing and computer vision library written in c) has implementation for hough transform (the simple hough transform find lines in an image, while the generalized one finds more complex objects) so that could be a good start. For the rectangles which do have closed corners there are also corner detectors such as cornerHarris which can help.
I ran the houghlines demo provided with opencv and here's the result on the image you gave (detected lines marked in red):
(source: splintec.com)
I believe you are looking for the generalized Hough transform.
In computer vision there is a algorithm called Generalized Hough Transform which maybe can solve your problem. There should be open source code having implemented this algorithm. Just search for it.
Assuming it's a reasonably noise free image (not a video of a screen) then one of the simple floodfill algorithms should work. You might need to run a dilate/erode on the image to close up the gaps.
The normal way to find lines is a Hough transform ( then find lines at right angles)
Opencv is the easiest way.
Take a look at this question OpenCV Object Detection - Center Point
There are several different approaches to your problem. I'd use a morphological image processing tool like this one. You will have the flexibility to define "rectangle" even something that not "exactly closed" (where the fill algorithm will fail).
Another possibility could be to use a machine learning approach, which basically is more data-driven than definition-driven like the previous one. You'll have to give your algorithm several "examples" of what a rectangle is, and it will eventually learn (with a bias and an error rate).
iterate from left to right until you hit a color pixel then use modified flood fill algorithm. more info on the algo flood fill # wiki
another approach would be to find ANY colored pixel on the image then go with
while(pixel under current is colored)
{
lowest pixel coordinate = pixel under current
current = pixel under
}
then do the same upwards.
now u have defined a single line. then use ends of the lines to approx match lines into rectangles. if they are not pixel perfect you could do some kind of tresholding.
The flood fill would work, or you could use a modification of an edge tracking algorithm.
what you do is:
create a 2d array (or any other d2 data struct)- each row represents a horizontal pixel line on screen, and each column a vertical line
iterate through all the pixels, left to right, and whenever you find a coloured one add its coordinates to the array
iterate through the array and findying lines and storing the begin and end pixel for each one (different data structure)
knowing that the begin of each line is its left/top pixel, you can easily check to see if any 4 lines comprise a rectangle
To get from the image you have with the nearly touching horizontal and vertical lines to just the rectangles:
Convert to binary (i.e. all lines
are white, the rest is black)
Perform a Binary dilation (here you make every pixel that touches a white pixel in the source image or is a white pixel in the source image white. Touch is straight only (so each pixel "touches" the pixels to its left, right, above and below it) this is called "4-connected"
repeat step 3 a few times if the gaps between the ends are larger then 2 pixels wide, but not too often!
Perform a skeleton operation (here you make every pixel in the output image black if it is a white pixel in the source image that touches at least one black pixel and the white pixels it touches (in the source image) all touch eachother. Again touch defined with 4-connectedness. See sample below.
Repeat step 4 untill the image doesn't change after a repeat (all white pixels are line ends or connectors)
This will, with a bit of luck, first show the boxes with thick fat lines, leaving thick fat artifacts all over the image (after step 3) and then then after step 5 all thick fat artifacts will have been removed, while all boxes remain. You need to tweek the number of repeats in step 3 for best results. If you're interested in image morphology, this is the book of a really good introductory course I took.
Sample: (0=black, 1=white, pixels in the center of each 3x3 block are being considered, input left, output right)
011 => 011
011 => 001 all other white pixels touch, so eliminate
011 => 011
010 => 010
010 => 010 top pixel would become disconnected, so leave
010 => 010
010 => 010
010 => 000 touches only one white pixel, so remove
000 => 000
010 => 010
111 => 111 does not touch black pixels, leave
010 => 010
010 => 010
011 => 011 other pixels do not touch. so leave
000 => 000