#image-processing #glsl #processing #shader #fragment-shader
Вопрос:
как проверить, есть ли целевой пиксель в определенной области экрана, например, проверить, есть ли целевой пиксель x < 100, y > 320. x и y-ширина и высота экрана.
в следующем коде я могу отслеживать средние значения x,y в targetpixel. этот код использует программу обработки эскиза и шейдера (glsl) спасибо за любую помощь
import processing.video.*;
PShader colorFinder, colorPosShader;
PGraphics overlay, posBuffer;
// Variable for capture device
Capture video;
// A variable for the color we are searching for.
color trackColor;
float threshold = 0.1;
void setup() {
//size(320, 240);
size(640, 480, P2D);
overlay = createGraphics(width, height, P2D);
posBuffer = createGraphics(width, height, P2D);
colorFinder = loadShader("colorDetect.glsl");
colorPosShader = loadShader("colorPos.glsl");
printArray(Capture.list());
video = new Capture(this, width, height);
video.start();
video.loadPixels();
// Start off tracking for red
trackColor = color(255, 0, 0);
}
void captureEvent(Capture video) {
// Read image from the camera
video.read();
}
void draw() {
colorFinder.set("threshold", threshold);
colorFinder.set("targetColor", red(trackColor) / 255.0, green(trackColor) / 255.0, blue(trackColor) / 255.0, 1.0);
colorPosShader.set("threshold", threshold);
colorPosShader.set("targetColor", red(trackColor) / 255.0, green(trackColor) / 255.0, blue(trackColor) / 255.0, 1.0);
overlay.beginDraw();
overlay.shader(colorFinder);
overlay.image(video, 0, 0);
overlay.endDraw();
posBuffer.beginDraw();
posBuffer.shader(colorPosShader);
posBuffer.image(video, 0, 0);
posBuffer.endDraw();
//compute average position by looking at pixels from position buffer
posBuffer.loadPixels();
PVector avg = new PVector(0, 0);
int count = 0;
for(int i = 0; i < posBuffer.pixels.length; i ){
// encoded so blue is > 0 if a pixel is within threshold
if(blue(posBuffer.pixels[i]) > 0){
count ;
// processing takes 0-1 (float) color values from shader to 0-255 (int) values for color
// to decode, we need to divide the color by 255 to get the original value
avg.add(red(posBuffer.pixels[i]) / 255.0, green(posBuffer.pixels[i]) / 255.0);
}
}
if(count > 0){
// we have the sum of positions, so divide by the number of additions
avg.div((float) count);
// convert 0-1 position to screen position
avg.x *= width;
avg.y *= height;
} else {
// appear offscreen
avg = new PVector(-100, -100);
}
image(overlay, 0, 0);
fill(trackColor);
stroke(0);
circle(avg.x, avg.y, 16);
fill(0, 50);
noStroke();
rect(0, 0, 150, 30);
fill(150);
//text("avg,x" avg.x, 0, 11);
//text("Threshold: " threshold, 0, 22);
println(frameRate);
println(count);
}
void mousePressed() {
// Save color where the mouse is clicked in trackColor variable
video.loadPixels();
int loc = mouseX mouseY*video.width;
trackColor = video.pixels[loc];
}
void mouseWheel(MouseEvent e){
threshold -= e.getCount() * 0.01;
threshold = constrain(threshold, 0, 1);
}
// this shader for detect color
//the shader to find pixels if they are within a threshold:
In shaders, colors are stored with 4 component vectors with
//each component ranging from 0 to 1. The components are usually marked x, y, z, and w
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D texture;
varying vec4 vertColor;
varying vec4 vertTexCoord;
//Uniform variables are constants in the shader, but can be modified by the external
//program that calls the shader, in this case the processing sketch
uniform vec4 targetColor;
uniform float threshold; //between 0 and 1
void main() {
// get pixel color
vec4 texColor = texture2D(texture, vertTexCoord.st) * vertColor;
vec3 a = texColor.xyz;
vec3 b = targetColor.xyz;
// compute "distance" between colors rgb components
float dist = sqrt((b.x - a.x) * (b.x - a.x) (b.y - a.y) * (b.y - a.y) (b.z - a.z) * (b.z - a.z));
// colors are from 0-1, so the max distance between colors is sqrt(3)
if(dist < threshold * sqrt(3)){
// display inverse color where pixels are within the threshold
texColor = vec4(1) - texColor;
}
// force alpha to be 1 since inverting the color makes the alpha zero
gl_FragColor = vec4(texColor.xyz, 1);
}
//this shader finding the positions of all detected pixels
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D texture;
varying vec4 vertColor;
varying vec4 vertTexCoord;//uv coordinates of the texture
//or uv coordinate of the current pixel on the screen
//uv coordinates are a 2D vector that ranges from 0-1 in each
//component, where a uv of (0, 0) means you are at
//the top-left corner of the texture and (1, 1) the bottom right
//To get the screen position, you multiply the uv by the screen width and height
uniform vec4 targetColor;
uniform float threshold; //between 0 and 1
void main() {
vec4 texColor = texture2D(texture, vertTexCoord.st) * vertColor;
vec3 a = texColor.xyz;
vec3 b = targetColor.xyz;
float dist = sqrt((b.x - a.x) * (b.x - a.x) (b.y - a.y) * (b.y - a.y) (b.z - a.z) * (b.z - a.z));
bool cond = dist < threshold * sqrt(3);
// if color is within threshold, encode the pixel's position into red and green components
// and use blue component as a marker that the pixel was in range
// vertTexCoord is from 0 to 1, so after computing average, multiply by width and height to get screen position
gl_FragColor = cond ? vec4(vertTexCoord.x, vertTexCoord.y, 1, 1) : vec4(0, 0, 0, 1);
}
Комментарии:
1. привет @Rabbid76 не хотели бы вы помочь мне в этом деле? Спасибо
2. Где находится код шейдера? Что такое целевой пиксель? Где вы хотите проверить «есть ли целевой пиксель в определенной области»? В шейдере фрагментов? Что вы хотите делать, когда фрагмент находится в определенной области?
3. @Rabbid76 я просто редактирую и добавляю код шейдера. Спасибо
4. @Rabbid76 я думаю, мне легко понять, произошла ли проверка пикселя в процессе обработки, хотя это можно сделать в файле шейдера, целевой пиксель — цвет дорожки, я хочу проверить, есть ли цвет дорожки между 0-100 осями x, также хочу проверить, есть ли цвет дорожки между 320 — высотой оси y, спасибо. я хочу найти расстояние между этим диапазоном областей и другой постоянной координатой, например, x = 150, y = 370. если расстояние меньше 50, я хочу отправить значение в arduino. Спасибо