Matlab- Improve code in image cropping black border

后端 未结 1 1766
独厮守ぢ
独厮守ぢ 2020-12-06 23:18

I have this code that crop the black borders in my picture.

I don\'t know why the border still exists.

I1=im2double(imread(\'dart.jpg\'));

sizeI = s         


        
相关标签:
1条回答
  • 2020-12-07 00:17

    This code works for me, assuming that your black border pixels are all zero. Should there be non-zero pixels in the black borders of your image (probably due to quantization and compression artifacts - your image is JPEG after all...), then this code will not work. What this code is doing is checking all of the columns first to see if there are any non-zero pixels. It then figures out where to crop by determining the first non-zero column and going to the last non-zero column. This code also assumes that the non-zero columns are symmetric, which is why you're dividing by 2 in your zeros statement. By the way, zeros is a built-in function in MATLAB. I don't recommend you create a variable that has this name, as your later code may require this function and you are unintentionally shadowing over this function with a variable.

    Nevertheless, here's what I did to test to see if your code works. I used a built-in image from MATLAB's system path cameraman.tif, and created a 10 pixel border surrounding the image. I then ran your code to see what I would get:

    im = imread('cameraman.tif');
    I1 = padarray(im2double(im), [10 10]);
    

    Running your code, this is the figure I get:

    enter image description here


    There exist certain preconditions when running that code so bear this in mind before using it:

    1. This assumes an entirely symmetric black border around the image.
    2. This assumes that all black border pixels are zero.
    3. If your border has non-zero pixels, even though it may visually look like there are non-zero pixels, then this code will not work.

    As such, I suggest you threshold your image by a small amount (perhaps intensity 10) to ensure that the borders are zero before you proceed. You would then use this image to calculate how many border pixels you have. As such, do something like this.

    I1=im2double(imread('dart.jpg')); %// Read in the image
    I1thresh = I1 >= (10/255); %// As an example - Note the division by 255 as you did im2double
    sizeI = size(I1);
    zeros = floor((sizeI(2) -  min(sum(any(I1thresh))))/2); %// Note the change in any
    I2 = I1(:, zeros : sizeI(2)-zeros, :); 
    I2thresh = I1thresh(:, zeros : sizeI(2)-zeros, :);  % // Note new variable
    nonZero = sum(any(I1thresh,2)); %// Note the change in any
    
    sizeI2 = size(I2);
    zerosRows = floor((sizeI(1) -  min(sum(any(I2thresh, 2))))/2); %// Note change in any
    I3 = I2(zerosRows : sizeI2(1)-zerosRows, :, :);
    
    subplot(1,3,1), imshow(I1);title('Figure 1');
    subplot(1,3,2), imshow(I2);title('Figure 2');
    subplot(1,3,3), imshow(I3);title('Figure 3');
    

    Edit - Non-uniform black borders

    From your comments, you have said that your black borders may not be symmetric. In that case, you need to have logic that determines the beginning of where the black borders are to where the end of the black borders are. You apply this for both the rows and the columns of the black borders. In that case, I would use the find command, and use the any operation along the rows and columns and determine the smallest and largest indices where the rows and columns are non-zero. This exactly corresponds to the minimum and maximum operations in MATLAB with respect to your code. I'm going to use the modified algorithm with thresholding to circumvent any quantization or compression artifacts. As such:

    I1=im2double(imread('dart.jpg')); %// Read in the image
    I1thresh = I1 >= (10/255); %// As an example - Note the division by 255 as you did im2double
    %// Removed as this is no longer needed 
    %// sizeI = size(I1);
    nonZeroCols = find(any(I1thresh)); %// Change
    minCol = min(nonZeroCols); %// Change
    maxCol = max(nonZeroCols); %// Change
    I2 = I1(:, minCol : maxCol, :); 
    I2thresh = I1thresh(:, minCol : maxCol, :);  % // Note new variable
    %// Commented out. Don't see this being used anywhere
    %//nonZero = sum(any(I1thresh,2)); %// Note the change in any
    
    %// Removed as this is no longer needed
    %//sizeI2 = size(I2);
    nonZeroRows = find(any(I2thresh, 2)); %// Change
    minRow = min(nonZeroRows); %// Change
    maxRow = max(nonZeroRows); %// Change
    I3 = I2(minRow : maxRow, :, :); %// Change
    
    subplot(1,3,1), imshow(I1);title('Figure 1');
    subplot(1,3,2), imshow(I2);title('Figure 2');
    subplot(1,3,3), imshow(I3);title('Figure 3');
    

    The above code should now work for any size black border.

    0 讨论(0)
提交回复
热议问题