首页 \ 问答 \ 检查颜色相似度算法太慢[重复](Checking color similarity algorithm is too slow [duplicate])

检查颜色相似度算法太慢[重复](Checking color similarity algorithm is too slow [duplicate])

我试图每50毫秒截取一次屏幕截图并删除所有与我在开始时决定的颜色不相似的颜色,但检查每个像素颜色的代码部分太慢,所以在结束它几乎每1.5秒做一次截图...这是代码:

public int upX = 114;
public int upY = 28;
public Size size = new Size(1137,640);
public Color rosa = Color.FromArgb(255, 102, 153);
public int tollerance = 20;

private void button1_Click(object sender, EventArgs e){
  button1.Enabled = false;
  do{
    Bitmap bmpScreenshot = screenshot();
    deleteColors(bmpScreenshot, rosa);
    picturebox1.image = bmpScreenshot;
    Application.DoEvents();
  } while (true);
}

public Bitmap screenshot() {
  Bitmap bmpScreenshot = new Bitmap(size.Width, size.Height, PixelFormat.Format16bppRgb555);
  Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);
  gfxScreenshot.CopyFromScreen(upX, upY, 0, 0, size);
  return bmpScreenshot;
}

public void deleteColors(Bitmap bitmap, Color colorToSave) {
  for (int i = 0; i < bitmap.Width; i++){
    for (int j = 0; j < bitmap.Height; j++){
      Color c = bitmap.GetPixel(i, j);
      if (!colorsAreSimilar(c, colorToSave, tollerance)){
        bitmap.SetPixel(i, j, Color.White);
      }
     }
   }
 }

public bool colorsAreSimilar(Color a, Color b, int tollerance) {
  if (Math.Abs(a.R - b.R) < tollerance && Math.Abs(a.G - b.G) < tollerance && Math.Abs(a.B - b.B) < tollerance) {
    return true;
  }
  return false;
}

屏幕截图部分需要17到21毫秒,所以它已经太高了,但删除部分需要1300毫秒,所以我想先修复它,但是......我不知道我能做些什么来使代码更轻松。


I'm trying to take a screenshot every 50 ms and remove all colors that are not similar to a color that I've decided in the beginning, but the part of code that check the color of every pixel is too slow, so in the end it do a screenshot almost every 1.5s... Here is the code:

public int upX = 114;
public int upY = 28;
public Size size = new Size(1137,640);
public Color rosa = Color.FromArgb(255, 102, 153);
public int tollerance = 20;

private void button1_Click(object sender, EventArgs e){
  button1.Enabled = false;
  do{
    Bitmap bmpScreenshot = screenshot();
    deleteColors(bmpScreenshot, rosa);
    picturebox1.image = bmpScreenshot;
    Application.DoEvents();
  } while (true);
}

public Bitmap screenshot() {
  Bitmap bmpScreenshot = new Bitmap(size.Width, size.Height, PixelFormat.Format16bppRgb555);
  Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);
  gfxScreenshot.CopyFromScreen(upX, upY, 0, 0, size);
  return bmpScreenshot;
}

public void deleteColors(Bitmap bitmap, Color colorToSave) {
  for (int i = 0; i < bitmap.Width; i++){
    for (int j = 0; j < bitmap.Height; j++){
      Color c = bitmap.GetPixel(i, j);
      if (!colorsAreSimilar(c, colorToSave, tollerance)){
        bitmap.SetPixel(i, j, Color.White);
      }
     }
   }
 }

public bool colorsAreSimilar(Color a, Color b, int tollerance) {
  if (Math.Abs(a.R - b.R) < tollerance && Math.Abs(a.G - b.G) < tollerance && Math.Abs(a.B - b.B) < tollerance) {
    return true;
  }
  return false;
}

The screenshot part take 17 to 21ms, so it's already too high, but the delete part take 1300ms, so I'd like to fix that before, but... I don't know what i could do to make the code lighter.


原文:
更新时间:2022-08-29 09:08

最满意答案

您必须查阅C库的文档。 根据标准( N1570 7.21.4.2 ,重点矿):

rename功能导致其名称为old指向的字符串的文件由new指向的字符串给出的名称知道。 该名称不再可以访问名为old的文件。 如果在调用重命名函数之前存在由new指向的字符串命名的文件,则该行为是实现定义的

在gcc rename的情况下:

如果oldname不是目录,则在重命名操作期间将删除名为newname的任何现有文件。 但是,如果newname是目录的名称,则在此情况下重命名失败。

但是 ,在VS的情况下:

新名称不能是现有文件或目录的名称。


You have to consult the documentation of your C library. According to the standard (N1570 7.21.4.2, emphasis mine):

The rename function causes the file whose name is the string pointed to by old to be henceforth known by the name given by the string pointed to by new. The file named old is no longer accessible by that name. If a file named by the string pointed to by new exists prior to the call to the rename function, the behavior is implementation-defined.

In the case of gcc rename:

If oldname is not a directory, then any existing file named newname is removed during the renaming operation. However, if newname is the name of a directory, rename fails in this case.

In case of VS, however:

The new name must not be the name of an existing file or directory.

相关问答

更多
  • 我想他们不是异步的,因为他们返回一个结果,告诉操作是否成功。 我相信问题的发生是因为在修改后运行scandir时,它可能使用内存中的“缓存”数据,而不是重新扫描文件系统。 I suppose they are not asynchronous, because they return a result telling if the operation was successful or not. I believe the problem happens because when you run scand ...
  • 你可以从这里得到一些帮助: - 重命名操作是以原子方式完成的 ,这意味着在重命名运行时没有其他会话可以访问任何表。 例如,如果您有现有的表old_table,则可以创建另一个具有相同结构但为空的表new_table,然后按如下方式(假定backup_table尚不存在)用空表替换现有表。 ............... 当您执行RENAME时,不能有任何锁定表或活动事务。 您还必须具有原始表上的ALTER和DROP权限以及新表上的CREATE和INSERT权限。 如果MySQL在多表重命名中遇到任何错误,它 ...
  • 我认为你有一些用rename变量,这就是为什么编译器给called object 'rename' is not a function 。 检查一下 。 如评论中所述,请提供有关您的代码的更多信息。 I think you have some variables named with rename, that's why compiler gives called object 'rename' is not a function. Check this one. As said in the commen ...
  • 这里, find . -type f -exec mv '{}' $(echo {}) \; 命令替换是不加引号的,因此在find之前它会在命令行中展开。 生成的结果命令是 find . -type f -exec mv '{}' {} \; 然后find用当前文件名替换{}两个副本。 如果命令替换是双引号,则会发生同样的情况。 但是,如果它是单引号,那么find将扩展其中的{} ,并运行mv ./somefile $(echo ./somefile)类的命令,除非目录$(echo .存在mv ./s ...
  • 我认为你应该将os.rename(f, f.replace(',',''))更改为os.rename(os.path.join(self.dirname, f), os.path.join(self.dirname, f.replace(',',''))) 。 本质上, rename函数需要文件的有效路径,如果文件不在当前目录中,则需要将基本目录路径连接到文件名。 I think you should change os.rename(f, f.replace(',','')) to os.rename(o ...
  • 在Windows实现.NET Framework中, System.IO.File.Move调用底层的Win32函数MoveFile 。 有关MoveFile的MSDN: 移动现有文件或目录,包括其子项。 它似乎与Windows资源管理器调用的功能相同。 所以是的,它做同样的事情,只是重命名,而不是复制/删除。 public static void Move(String sourceFileName, String destFileName) { ... ... if (!Win ...
  • 要在Windows中正确重命名文件,您可能需要尝试使用(非标准) _wrename() CRT函数。 请注意,Windows使用Unicode UTF-16作为其默认的Unicode编码。 因此,通常,当将Unicode字符串传递给Win32 API或CRT函数(如上所述)时,应使用UTF-16编码。 To properly rename files in Windows, you may want to try using the (non-standard) _wrename() CRT functio ...
  • 您没有拥有要将文件移动到的目录: /Users/Username/... 是一个用户拥有的目录,因此您可以在那里操作文件。 /Library 不是用户拥有的目录。 为了操作非用户拥有目录中的文件,您需要提升权限。 您应该使用 ~/Library ,而不是使用 ~/Library ,这是用户拥有的目录。 ~/Library是/Users/Username/Library的简写名称。 You don't own the directory you're trying to move files into: /U ...
  • 每个反斜杠应该被另一个反转: char oldname[] ="C:\\Users\\Mohammed Mehdi\\Documents\\Test.txt"; char newname[] ="C:\\Users\\Mohammed Mehdi\\Documents\\Test"; 尝试添加 puts(oldname); puts(newname); 在进行该更改之前和之后,以查看路径实际上是如何。 您还应该从Visual Studio中获得警告: warning C4129: 'M' : unrec ...
  • 您必须查阅C库的文档。 根据标准( N1570 7.21.4.2 ,重点矿): rename功能导致其名称为old指向的字符串的文件由new指向的字符串给出的名称知道。 该名称不再可以访问名为old的文件。 如果在调用重命名函数之前存在由new指向的字符串命名的文件,则该行为是实现定义的 。 在gcc rename的情况下: 如果oldname不是目录,则在重命名操作期间将删除名为newname的任何现有文件。 但是,如果newname是目录的名称,则在此情况下重命名失败。 但是 ,在VS的情况下: 新名称 ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)