- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在寻找基于图像中任意颜色计算方向矢量的最快方法(Rpi 相机,但现在可以使用 JPEG 文件进行测试),也就是跟踪彩球项目。请注意,生成的向量(或质心坐标等)需要传递给 PHP 以执行程序,因此我正在寻找的解决方案需要以 PHP 结尾,但之前可以是任何东西,因为它可以在Windows 和 Linux。
考虑输入 JPEG 图像:
这是我所追求的 2 个示例方向向量,它们是基于 1)蓝绿色输入和 2)紫色输入获得的。显然,一次只会询问 1 个向量,我将 2 个用于在 1 个图像中演示多个示例,但一次总是只有 1 个向量。请注意,生成的向量(“v”)被标准化为 -1.0(底部/左侧)到 +1.0(底部/右侧),因此零是图片的中间。
以下是我迄今为止实现/测试的各种解决方案以及整个过程需要多少时间,基于 960x640 JPEG 图片,但实现的解决方案将与 Rpi 相机输入相关联,我还没有相机所以在相机从中国运到之前,我使用 JPEG 图像。
1) 2700ms :使用与 PHP 捆绑的 GD2,for 循环遍历每个像素,在 XY 数组中推送匹配 ~10% RGB 值的像素,平均 XY 数组,计算/归一化来自 XY 数组的方向向量。
$arr_matching_pixels = array('arr_x' => array(), 'arr_y' => array());
for($y = 0; $y < $h - 1; $y++){
for($x = 0; $x < $w - 1; $x++){
$arr_pixel = imagecolorsforindex($img, imagecolorat($img, $x, $y));
if(abs($arr_pixel['red'] - $arr_seek_color['red']) < 30){
if(abs($arr_pixel['green'] - $arr_seek_color['green']) < 30){
if(abs($arr_pixel['blue'] - $arr_seek_color['blue']) < 30){
array_push($arr_matching_pixels['arr_x'], $x);
array_push($arr_matching_pixels['arr_y'], $y);
}
}
}
}
}
// Compute centroid of color... etc...
imagecreatefromjpeg('_test_cam_img.jpg');
将 Canvas 大小调整 50%(可接受的损失)
$imagick = new Imagick(realpath($o_img));
$arr_matching_pixels = array('arr_x' => array(), 'arr_y' => array());
$arr_pixel = array();
$iterator = $imagick->getPixelIterator();
foreach($iterator as $y => $pixels){
foreach($pixels as $x => $pixel){
$arr_pixel = $pixel->getColor();
if(abs($arr_pixel['r'] - $arr_seek_color['red']) < 30){
if(abs($arr_pixel['g'] - $arr_seek_color['green']) < 30){
if(abs($arr_pixel['b'] - $arr_seek_color['blue']) < 30){
array_push($arr_matching_pixels['arr_x'], $x);
array_push($arr_matching_pixels['arr_y'], $y);
}
}
}
}
}
// Compute centroid of color... etc...
$imagick = new Imagick(realpath($o_img));
$out = exec('"E:\Users\Ben\Roaming Apps\imagemagick-6.9.3\convert" E:\wamp64\www\test_cam_img.jpg -resize 50% -fuzz 10% +transparent rgb(' . $arr_seek_color['red'] . ',' . $arr_seek_color['green'] . ',' . $arr_seek_color['blue'] . ') sparse-color:');
$arr_lines = explode(' ', $out);
$arr_matching_pixels = array('arr_x' => array(), 'arr_y' => array());
foreach($arr_lines as $str_line){
$arr_xy_coords = explode(',', $str_line);
array_push($arr_matching_pixels['arr_x'], $arr_xy_coords[0]);
array_push($arr_matching_pixels['arr_y'], $arr_xy_coords[1]);
}
// Compute centroid of color... etc...
file_put_contents('_avg_color_coords_in.txt', $o_img . "\n" . $arr_seek_color['h'] . ',' . $arr_seek_color['s'] . ',' . $arr_seek_color['l']);
$starttime = time();
while((time() - $starttime) < 5){ // Max 5 seconds (exaggerated)
if(file_exists('_avg_color_coords_out.txt')){
$dir_vector = (float) file_get_contents('_avg_color_coords_out.txt');
if(!@unlink('_avg_color_coords_out.txt')){
sleep(1);
unlink('_avg_color_coords_out.txt');
}
break;
}
usleep(2000);
}
// $dir_vector ("v", the centroid of the color) is already computed by Python
// ---------- PYTHON SCRIPT ----------
import math
import cv2
import numpy as np
import os
import time
#cap = cv2.VideoCapture(0)
#while (1):
# _, frame = cap.read()
if(os.path.exists('_avg_color_coords_stop.txt')):
exit()
while not os.path.exists('_avg_color_coords_in.txt'):
time.sleep(0.002)
f = open('_avg_color_coords_in.txt', 'r')
imgsrc = f.readline().rstrip('\n')
rgbcol = [int(x) for x in f.readline().rstrip('\n').split(',')]
frame = cv2.imread(imgsrc)
h, w = frame.shape[:2]
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
hfacl = rgbcol[0] / 360 * 180 * 0.95
hfach = rgbcol[0] / 360 * 180 * 1.05
sfacl = rgbcol[1] / 100 * 255 * 0.9
sfach = rgbcol[1] / 100 * 255 * 1.1
vfacl = rgbcol[2] / 100 * 255 * 0.9
vfach = rgbcol[2] / 100 * 255 * 1.1
lower_color = np.array([hfacl, sfacl, vfacl]) # 0..180, 0..255, 0..255 not percentage!
upper_color = np.array([hfach, sfach, vfach]) # 0..180, 0..255, 0..255 not percentage!
mask = cv2.inRange(hsv, lower_color, upper_color)
#cv2.imshow('mask', mask)
points = cv2.findNonZero(mask)
if(points.any()):
avg = np.mean(points, axis=0)
else:
avg = [0,0]
#print(avg)
v = -math.atan(((w * 0.5) - avg[0][0]) / (h - avg[0][1])) / (3.1415 * 0.5);
f2 = open('_avg_color_coords_out.txt', 'w+')
f2.write("%s" % str(v))
# k = cv2.waitKey(5) & 0xff
# if k == 27:
# break
#cv2.destroyAllWindows()
#cap.release()
f2.close()
f.close()
os.remove('_avg_color_coords_in.txt')
最佳答案
我快速进入 php-vips :
#!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips;
$image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']);
# Target colour in RGB.
$target = [50, 10, 100];
# Select pixels where all bands are less than 10 away from the target.
# (and render it to memory ... we'll be reusing this mask image).
# The mask image will have one band with 0 for false and 255 for true.
$mask = $image->subtract($target)->abs()->less(10)->bandand()->copyMemory();
# The number of set pixels in the mask.
$n_set = $mask->avg() * $mask->width * $mask->height / 255;
# Handy for debugging: uncomment to write the mask image for inspection.
# $mask->writeToFile("x.png");
# Make a two-band image where band 0 is x coordinates and band 1 is y
# coordinates.
$coords = Vips\Image::xyz($mask->width, $mask->height);
# Make an indexed histogram: sum $coords at each position.
$pos = $coords->hist_find_indexed($mask);
# fetch the sum of the 255 value (true) pixels
[$x_sum, $y_sum] = $pos->getpoint(255, 0);
echo("x = " . $x_sum / $n_set . "\n");
echo("y = " . $y_sum / $n_set . "\n");
$ time ./locate-rgb.php ~/pics/x.jpg
x = 483.375
y = 487.75
real 0m0.079s
user 0m0.085s
sys 0m0.022s
关于php - 计算图像中任意颜色质心并将其提供给 PHP 的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58649231/
前言 一年一度的虐狗节终于过去了,朋友圈各种晒,晒自拍,晒娃,晒美食,秀恩爱的。程序员在晒什么,程序员在加班。但是礼物还是少不了的,送什么好?作为程序员,我准备了一份特别的礼物,用以往发的微博数据
默认情况下,我有一个 V3 map 加载并以特定的经度/纬度为中心。加载后,用户可以输入他们的地址以获取前往该地点的路线。发生这种情况时, map 会调整大小以适应其左侧的方向框。因此,路线在 map
我是一名优秀的程序员,十分优秀!