简体   繁体   English

如何通过图像表达来操作像素值?

[英]How to manipulate pixel values via image expression?

Recently I am writing a script to manipulate the pixel values in an image.最近我正在编写一个脚本来操作图像中的像素值。 The idea is to set the pixels that fall into the given range to a specific value.这个想法是将落入给定范围内的像素设置为特定值。 Instead of using the command "for" which loops from pixel to pixel, an image expression was utilized, for example:不是使用从像素到像素循环的命令“for”,而是使用图像表达式,例如:

Img = (Img>=thresh_Low && Img<=thresh_Up ? 0 : Img)

Here comes the question: if I would like to replace the pixel value with the average of neighbouring pixels, rather than just a fixed value such as 0 in the above case, pixel-looping seems not avoidable anymore.问题来了:如果我想用相邻像素的平均值代替像素值,而不仅仅是上面例子中的 0 之类的固定值,那么像素循环似乎就无法避免了。 Does anyone know any workaround that the method of image expression can still be used here?有谁知道这里仍然可以使用图像表达的方法的任何解决方法?

Thanks in advance.提前致谢。

Computing images expressions is much more efficient than any pixel-by-pixel operation.计算图像表达式比任何逐像素操作都要高效得多。 Even if you thereby compute some averages that are not needed will the script perform a lot faster.即使您因此计算了一些不需要的平均值,脚本也会执行得更快。 Therefore:所以:

You should compute an average-image (for all pixels, not just the masked ones) and then use it in the masked assignment.您应该计算一个平均图像(对于所有像素,而不仅仅是蒙版的像素),然后在蒙版分配中使用它。

The following example illustrates this.以下示例说明了这一点。 Only the last two lines are the direct answer to your question.只有最后两行是您问题的直接答案。 The condition is used to either copy the orignal or the averaged value:该条件用于复制原始值或平均值:

number aver_NN = 3      // Next neighbor averaging. 1 = 3x3, 2 = 5x5 etc.)
number maskRad = 0.3    // just a radius to show masking

image img := GetFrontImage()
if ( 2 != img.ImageGetNumDimensions() ) Throw( "Only 2D images are supported." )

// Create average image (ignoring border region for simplicity)
image av := img * 0
for( number dx=-aver_NN; dx<=aver_NN; dx++ )
    for( number dy=-aver_NN; dy<=aver_NN; dy++ )
        av += img.offset(dx,dy)

av /= (2*aver_NN + 1) ** 2

// Apply masked replacement
image replaced = iradius < iwidth*maskrad ? av : img
replaced.ShowImage()

Further explanations because of comments below由于以下评论的进一步解释

The averaging is done by shifting the whole image by one pixel using the offset command.平均是通过使用offset命令将整个图像移动一个像素来完成的。 This command will replace border pixels with the 0 value.此命令将用0值替换边界像素。 Summing all the shifted images and dividing by the number of images therefore gives at each pixel the average value of the neighbor pixels, but the normalization in the border pixels is incorrect.将所有移位的图像相加并除以图像的数量,因此在每个像素处给出了相邻像素的平均值,但边界像素中的归一化是不正确的。 The following script shows this using explicit images instead of the for-loop:以下脚本使用显式图像而不是 for 循环显示了这一点:


number size = 25
image test := realimage("Source",4,size,size)
test = 1 + random()
test.ShowImage()

image offset_N = test.offset(  0, -1 )
image offset_S = test.offset(  0,  1 )
image offset_W = test.offset( -1,  0 )
image offset_E = test.offset(  1,  0 )
offset_N.ShowImage()
offset_N.SetName("N")
offset_S.ShowImage()
offset_S.SetName("S")
offset_W.ShowImage()
offset_W.SetName("W")
offset_E.ShowImage()
offset_E.SetName("E")

image average = test + offset_N + offset_S + offset_W + offset_E
average /= 5
average.SetName("Average")
average.ShowImage()

EGUPerformActionWithAllShownImages("Arrange")

输出

To fix the issue with the borders, two strategies could be used for the normalization.为了解决边界问题,可以使用两种策略进行标准化。

  • Explicitly normalize subsections of the sum-image, knowing how many images where summed:明确归一化总和图像的子部分,知道求和的图像数量:
...

image average = test + offset_N + offset_S + offset_W + offset_E
average.SetName("Average")
// Divide corners by 3
// Divide edges by 4
// Divide rest by 5
average.slice2(0,0,0 ,0,2,size-1, 1,2,size-1) /= 3
average.slice2(1,0,0 ,0,size-2,1, 1,2,size-1) /= 4
average.slice2(0,1,0 ,0,2,size-1, 1,size-2,1) /= 4
average.slice2(1,1,0 ,0,size-2,1, 1,size-2,1) /= 5

...
  • Create a second image which 'counts' automatically and used it for normalization.创建第二张自动“计数”的图像并将其用于标准化。 For this, simple create a 1 -valued image of the same size as the source and perform the same summing steps: This makes the script from above into:为此,只需创建一个与源大小相同的1值图像并执行相同的求和步骤:这使得上面的脚本变成:
number aver_NN = 2      // Next neighbor averaging. 1 = 3x3, 2 = 5x5 etc.)
number maskRad = 1    // just a radius to show masking

image img := GetFrontImage()
if ( 2 != img.ImageGetNumDimensions() ) Throw( "Only 2D images are supported." )

// Create average image 
image av = img * 0
image weight = av 
image proxy = av + 1

for( number dx=-aver_NN; dx<=aver_NN; dx++ )
{
    for( number dy=-aver_NN; dy<=aver_NN; dy++ )
    {
        av += img.offset(dx,dy)
        weight += proxy.offset(dx,dy)
    }
}

weight.SetName("Sum weight")
weight.showImage()

av /= weight

// Apply masked replacement
image replaced = iradius < iwidth*maskrad ? av : img
replaced.ShowImage()
  • One can also create the average image by relying on the inbuilt Convolution() command, which correctly handles the border cases right away.还可以依靠内置的Convolution()命令创建平均图像,该命令可以立即正确处理边界情况。 Here, one would just create the average image as:在这里,只需将平均图像创建为:
// Create average image 
// Define an averaging kernel
image kernel := [5,5] : {
 { 0, 0, 1, 0, 0 },
 { 0, 1, 1, 1, 0 },
 { 1, 1, 1, 1, 1 },
 { 0, 1, 1, 1, 0 },
 { 0, 0, 1, 0, 0 } 
}

image av = img.Convolution(kernel)
av.ShowImage()

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

相关问题 需要如何使用iPhone SDK创建/操作图像像素数据的示例 - Need example of how to create/manipulate image pixel data with iPhone SDK 如何在Xcode中操作CGImageRef中的像素值 - How can I manipulate the pixel values in a CGImageRef in Xcode 如何有效处理大量图像的像素值? - How do I manipulate a large number of images' pixel values effectively? 在 Flutter 中,如何在不使用图像 package 的情况下逐个像素地操作 ui.Image 的像素? - In Flutter, how to manipulate pixel by pixel of an ui.Image without using the Image package? 如何获取图像的像素值并将其存储到数组中? - How to get pixel values of an image and store it into an array? 如何在Silverlight Image控件中读取像素值? - How to read pixel values in Silverlight Image control? 如何获取iphone上图像上像素的RGB值 - How to get the RGB values for a pixel on an image on the iphone 如何在matlab中更改rgb图像中的像素值 - how to change the pixel values in a rgb image in matlab 如何将灰度图像转换为像素值列表? - How to convert a grayscale image into a list of pixel values? 如何将 excel 文件中的像素值转换为图像? - How to convert pixel values in excel file into an image?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM