8

I'd like to have a quicker review process of my photos when I dump them from the camera to the computer. Surely there are some parameters that I can extract programmatically from the photos and this value might be enough to automatically put some photos in the 'discard' pile.

I'm thinking in algorithms to detect edges, get average sharpness/blurriness of the image or something like that.

I know that this script won't really discard all bad photos and keep the good ones, but I'm hoping to discard the totally crap ones.

I'm pretty sure I can program a shell script using ImageMagick (but I'm open to any command line software) to get what I would need. The problem is that I don't know which values should I look for to get better results.

TLDR; what things should I look to be able to discard an image programmatically (edge detection, sharpness)?

I'm using Fedora Linux.

edit: I don't think this question is a duplicate of Is there photo analysis software which will pre-sort images by identifying potential technical problems? because that question asks for software recommendation and is suggested to make a workflow change in the answers (and using software that isn't available on linux), while I'm asking for what will give better results in detecting bad photos.

  • 3
    I'd be excited to see the answer to this, but I'm not sure there is one. For example, imagine a dramatic photo of an insect or other moving subject where 95% of the image is blurred or out of focus. There are many other examples where programmatically evaluating aesthetics may erroneously eliminate some of your best images. At any rate, I'd love to see how this evolves. – A K Jun 2 '15 at 21:45
  • 2
  • 2
    I would certainly look at blown highlights as a factor. – chili555 Jun 3 '15 at 1:45
  • 1
    You could detect camera shake, over/under exposure easily enough, and if you were really smart you could attempt to identify the subject of the photo to test whether it was in focus, but that's about it. – Matt Grum Jun 3 '15 at 9:38
  • 2
    Even detecting under- or over-exposure is difficult, because what about cases where you wanted it that way? What if the image is either high or low key (for effect or just because that's how the scene was). – mattdm Jun 3 '15 at 12:07
5

A reasonable answer to this would be "it depends" (another perspective is to "battle a little against the idea of objective metrics")

I'd recommend consulting this chart to determine how long you should spend trying to figure out a quicker way if 'quickness' is what you are looking for.

enter image description here

However if you decide to approach this as an exercize in understanding computational image analysis have a look at OpenCV.

To begin, you'll probably need a clearer definition of "totally crap". I'd suggest a data driven approach; go through a reasonable sample of your images manually, roughly divide into good/bad/crap (G/B/C) have a closer look at any features which could separate C from G or B, try to describe these features as simply as possible (e.g. color levels, blurred, too light, too dark, etc+). translate this into OpenCV terms. write some code to test the theory. classify. repeat until satisfied.

1

Depending on the language you're using OpenCV as suggested above or it's .net equivilent Emgu. Basically you'll want to Grayscale the image, then use a Laplacian Blur, then get the image data and check theimage to see if it's within a threshold range. If it's in a certain range the image isn't blurry, if the image is outside that range, it is.

Below is my implementation of multiple photos using VB.net

  Public Sub GetBlur()
    Dim List As String() = Directory.GetFiles("E:\Dartmoor\", "*.JPG")


    For Index As Integer = 1 To 2000
        Dim imgfile As String = List(Index)
        Dim Image As Drawing.Bitmap = Drawing.Bitmap.FromFile(imgfile)
        Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(Image)
        Dim factor As Single()
        Dim imgB As Drawing.Bitmap = New Drawing.Bitmap(imgfile)
        imgB = New Drawing.Bitmap(imgB)
        Dim imgGray As Image(Of Gray, Byte) = img.Convert(Of Gray, Byte)()
        Dim imgTmp As Image(Of Gray, Single) = imgGray.Laplace(1)
        Dim maxLap As Short = -32767
        For Each MyByte As Single In imgTmp.Data
            If MyByte > maxLap Then

                maxLap = MyByte

            End If
        Next

        If maxLap > 300 Or maxLap < 150 Then
            List(Index) = imgfile & " is blurry"

        Else
            List(Index) = imgfile & " isn't blurry"
        End If

        '    'This saves the location of where the user is currently if they need to pause





        imgGray.Dispose()
        img.Dispose()
        imgTmp.Dispose()
        imgB.Dispose()

    Next
    Using sw As StreamWriter = New StreamWriter("Result.txt")
        For i As Integer = 1 To 2000
            sw.WriteLine(List(i))
        Next
    End Using
End Sub
  • This doesn't answer the question, what things should I look to be able to discard an image programmatically (edge detection, sharpness)? This sounds like an implementation of the suggestion in another answer. – scottbb Jan 4 '18 at 0:04
  • First of all, I would recommend not deleting anything that the progam says is blurry. Because it is never 100% perfect. The original poster said to check if it's bad. So this implementation would work for that. This implementation uses edge detection. The problem is that "bad" is very varied and when I think bad, I think blurry and stuff. – Simon Dolby Jan 4 '18 at 13:48
  • But it seems that a composition with a small well-focused subject, with lots of creative blurriness (bokeh), would be kicked out as mostly blurry. So intentional blur fails this check. (I also agree, I wouldn't delete anything a program told me was "bad". Computers can't interpret art well) – scottbb Jan 4 '18 at 15:33
  • That is a very fair point regarding the creative blur. That's going to be very hard to fix. I would imagine, trying to find a good range that includes the creative blur. Or creating a seperate routine that checks for creative blurriness which would of course have a seperate range. My range was created as a result of 40 images blur checked. – Simon Dolby Jan 5 '18 at 17:07
1

ImageMagick is your friend here. You are going to be writing a lot of scripts that call it's prorrams.

E.g. Image arithmetic:

Take the image. Blur it to a new image. Subtract image 2 from image 1, taking the absolute value of the result. Sum the pixels of the result, and average. Threshold.

A sharp image is considerably different from the blurred image, and so the average value of the subtraction will be high.

A blurry image is much less different from a blurred blurry image.

As one of the comments to another answer points out, sometimes an image is intentionally blurry. Some people actually like bokeh. So put another step in and take the middle third or middle quarter of the image.


Take the histogram of the image. If more than X% of the pixels are saturated (>248) for any channel, then the highlights are blown.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.