简体   繁体   English

加快Matlab代码以消除白色像素

[英]speed up matlab code for eliminating white pixels

I have rgb images from a camera which contain white pixels. 我有来自相机的RGB图像,其中包含白色像素。 I wrote the following code to eliminate them. 我编写了以下代码以消除它们。 It works but takes forever. 它有效,但需要永远。

% elliminate white pixel    
while 1
    maxValue = max(imageRGB(:));        
    [maxY maxX] = maxPosition(squeeze(imageRGB(:,:,c)));
    surr = 2;
    x_l = maxX - surr; if x_l < 1, x_l = 1; end
    x_r = maxX + surr; if x_r > size(imageRGB,2), x_r = size(imageRGB,2); end
    y_u = maxY - surr; if y_u < 1, y_u = 1; end
    y_b = maxY + surr; if y_b > size(imageRGB,1), y_b = size(imageRGB,1); end
    meanArea = ((y_b-y_u)+1) * ((x_r-x_l)+1) - 1;
    mean = (sum(sum(imageRGB(y_u:y_b, x_l:x_r,c))) - maxValue)/meanArea;        
    if (maxValue/mean > 1.5)
        imageRGB(maxY,maxX,c) = mean;
    else
        break;
    end
end

Any ideas how to speed up this code´? 有什么想法可以加快此代码的速度吗?

Correct me if I'm wrong, or ignore this 'answer' entirely, but the code posted appears to: 如果我错了,请更正我,或者完全忽略此“答案”,但是发布的代码显示为:

  1. Find the most white pixel in the image (I'm guessing here, imageRGB isn't a Matlab built-in). 找到图像中最白的像素(我在这里猜, imageRGB不是内置的Matlab)。
  2. Find the position in the image of the most white pixel (another guess, another unknown function maxPosition ). 查找图像中最白的像素的位置(另一个猜测,另一个未知函数maxPosition )。
  3. Do some sort of averaging to replace the most-white pixel with an average over its immediate neighbourhood. 进行某种平均,以将最白的像素替换为其附近区域的平均值。
  4. Repeat the process until the stopping criterion is satisfied. 重复该过程,直到满足停止条件为止。

If you have the Image Processing Toolbox, you will find that it has all sorts of functions for adjusting pixel intensity which is, I think, what you are trying to do, so you can stop reading this answer now. 如果您拥有图像处理工具箱,您会发现它具有用于调整像素强度的各种功能,我想这是您要尝试做的事情,因此您现在就可以停止阅读此答案。 If you don't have the toolbox, read on. 如果您没有工具箱,请继续阅读。

If you can, you should amend your entire approach and decide, from one read of the image, what the threshold for averaging should be. 如果可以的话,您应该修改整个方法,并通过一次读取图像来确定平均阈值。 This would lift the computation of maxValue out of the loop, maybe replace it by a single computation of thresholdValue . 这样可以将maxValue的计算带出循环,或者将其替换为thresholdValue的单个计算。 Then you could lift the calculation of [maxY maxX] out of the loop too. 然后,您也可以将[maxY maxX]的计算移出循环。

If you can't do this, there are still some options for increasing the speed of your operations. 如果您无法执行此操作,则仍然可以使用某些选项来提高操作速度。 You could either: 您可以:

  • Pad the image with a 2-pixel halo all round before starting operations. 开始操作之前,请使用2像素光晕全面填充图像。 Then apply your operation to all the white pixels in the original image. 然后将操作应用于原始图像中的所有白色像素。 Obviously you'll have to set the halo pixels to the right value to leave your operation unchanged. 显然,您必须将光晕像素设置为正确的值才能使操作保持不变。

or 要么

  • Operate only on the pixels in the image which are not within 2 pixels of the edge. 仅在图像边缘上2像素以内的像素上操作。 This will produce an output image which is 4 pixels smaller in each dimension, but on large images this is often not a problem. 这将产生输出图像,每个方向上的输出图像要小4个像素,但是在大图像上,这通常不是问题。

Either of these eliminates a whole slew of if statements and the repeated calculation of meanArea (since it becomes a constant). 这两种方法都消除了整个if语句和对meanArea的重复计算(因为它变为常数)。

If you can calculate a threshold once, at the start of processing, rather than recalculating it iteratively you might find that you can write a function to implement the averaging which you can apply to all the pixels in the image, and eliminate the need to find the white pixels. 如果您可以一次计算阈值,那么在处理开始时,而不是迭代地重新计算阈值,您可能会发现您可以编写函数来实现求平均值,并将其应用于图像中的所有像素,从而消除了寻找白色像素。 The function would have to leave the un-white pixels unchanged of course. 当然,该功能必须使非白色像素保持不变。 Applying an operation to every pixel, ensuring that it is a null-operation for the pixels which should not be changed (or an identity operation for those pixels) is sometimes faster than first finding the pixels that need to be changed and then applying the operation only to those pixels. 将操作应用于每个像素,确保对不应该更改的像素执行空操作(或对那些像素执行标识操作)有时比先找到需要更改的像素然后应用操作要快仅限于那些像素。

  • From what I know if perform poorly. 据我了解, if表现不佳。

you could replace 你可以取代

 x_l = maxX - surr; if x_l < 1, x_l = 1; end

with

 x_l = max(maxX - surr,1); 

and the others analogous. 其他类似。

Also you could put the (maxValue/mean > 1.5) in the condition for the while loop. 您也可以将(maxValue/mean > 1.5)设置为while循环的条件。


  • in the lines 在行中

    maxValue = max(imageRGB(:)); maxValue = max(imageRGB(:));
    [maxY maxX] = maxPosition(squeeze(imageRGB(:,:,c))); [maxY maxX] = maxPosition(squeeze(imageRGB(:,:,c)));

you search for max twice. 您最多搜索两次。 I suppose you could save some time if you write it like: 我想如果您这样写,您可以节省一些时间:

[maxY maxX] = maxPosition(squeeze(imageRGB(:,:,c)));
 maxValue = imageRGB(maxY,maxX,c);   

Another possibility would be to remove the sorting and just calculate the average on the whole image. 另一种可能性是删除排序,仅计算整个图像的平均值。 This is easily done with conv2 which is a built-in and therefor very fast compared to anything anyone of us could cook up. 使用内置的conv2可以轻松完成此操作,因此与我们任何人都可以做的任何事情相比,它都非常快。

Assuming you are working with double gray-scale images: 假设您正在处理双灰度图像:

% generate an averageing filter
filterMat=ones(2*filterSize+1);
filterMat=filterMat/sum(filterMat(:));

% convolve with image
meanComplete=conv2(picture,filterMat,'same');

% calculate the decision criterion
changeIndices=picture./meanComplete>relThreshold & picture>absThreshold;

% use logical indexing to replace white pixels with the mean
newPicture=picture;
newPicture(changeIndices)=mean(changeIndices);

I need 50ms for one Full-HD image. 一幅全高清图像需要50毫秒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM