96SEO 2026-02-19 19:12 13
12023年8月4日#xff0c;9点20分。

分离发挥题思路和基础题思路#xff0c;增加了博主Huiye…前言
1因为博客编辑字数超过1W字会导致MD编辑器非常卡顿。
所以我将发挥题和基础题的思路拆开了。
12023年8月4日9点20分。
分离发挥题思路和基础题思路增加了博主Huiyeee整体代码增加关于红点被黑带吸收问题的调试方法
22023年8月4日15点55分。
回答追小球代码中的目标值是那个。
1首要目的是让PC端的IDE上人们肉眼能够看到红色激光。
所以外面要适当调整下面初始化部分代码。
4设置亮度因为是从OpenART移植过来的所以亮度不能是3000。
使用OpenMV的同学请注意应该是-3到3.
5曝光度可以按照另外一位博主的来。
通过调整曝光度可以控制图像的明暗程度从而创造出不同的视觉效果。
我们这里没有使用sensor.set_auto_exposure()函数设置曝光度所以是默认打开了的。
你们可以看看另外一位博主的思路和调整。
6我们图像识别要关闭白平衡和自增益。
但是如果调节出来没结果。
可以尝试打开看看有木有优化
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
跳过帧3注意这一阶段只需要调整摄像头的初始化PC端IDE出现了红色斑点再开始处理
1保持色彩一致性在某些图像识别应用中特别是涉及色彩信息重要性较高的场景关闭白平衡可以保持图像中的色彩一致性。
白平衡会根据不同光源调整图像颜色这可能导致相同对象在不同光照条件下的颜色出现差异影响识别的准确性。
2特定光照条件下的优化在一些特殊环境中如低光照条件或强烈光线照射的情况下关闭自增益可以避免图像过度曝光或欠曝光。
这样做可以保留图像中更多细节有助于图像识别算法更好地处理图像。
3原始数据分析在某些图像分析应用中关闭白平衡和自增益可以使用原始的传感器数据进行分析而不受相机的颜色处理和亮度调整影响。
这可以提供更纯粹、更原始的数据有助于一些特定图像处理和识别算法的优化。
2需要注意的是关闭白平衡和自增益也可能导致一些挑战比如图像中的颜色信息可能会出现较大的变化而且在某些场景下可能需要更复杂的图像处理算法来应对不同光照条件下的挑战。
因此在图像识别应用中是否关闭白平衡和自增益需要根据具体的情况和应用场景进行权衡和决策。
1我个人认为这个必须上PID了。
我个人认为这个题目和OpenMV的追小球云台代码类似。
2基础题目我认为一个OpenMV就可以完成。
而发挥题目需要两个OpenMV。
这两个OpenMV一个放红色激光笔一个放绿色激光笔。
3各位可以综合追小球云台的代码以及我下面讲的关于C站那位博主代码的注意事项
3使用多组颜色阈值就像OpenMV多颜色识别详解的代码那样。
让识别的颜色阈值变成多组。
提高分辨效果。
如果基础题做出来了以及发挥题的追踪做出来了。
那么就直接用基础题的红色激光笔走然后发挥题追踪。
这个和上面的代码应该是差不多的。
这个我还是建议自己焊接一个按键并联一个104的电容进行硬件方面的按键消抖。
然后自己写逻辑代码。
2因为GitHub是在外网所以我直接复制过来了。
但是总是有一些网友硬要官方的GitHub链接。
我也贴到了前言部分。
#从内置pyb导入servo类也就是舵机控制类pan_servoServo(1)
#定义两个舵机对应P8引脚pan_servo.calibration(500,2500,500)
tilt_servo.calibration(500,2500,500)red_threshold
imax90)#在线调试使用这个PIDsensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.set_auto_whitebal(False)
追踪帧率影响不大#__________________________________________________________________
#定义寻找最大色块的函数因为图像中有多个色块所以追踪最大的那个
max_blob#__________________________________________________________________
img.find_blobs([red_threshold])
max_blob.cx()-img.width()/2tilt_error
max_blob.cy()-img.height()/2print(pan_error:
pan_error)img.draw_rectangle(max_blob.rect())
在找到最大色块画一个矩形框img.draw_cross(max_blob.cx(),
cypan_outputpan_pid.get_pid(pan_error,1)/2tilt_outputtilt_pid.get_pid(tilt_error,1)
#上面两个都说进行PID运算print(pan_output,pan_output)pan_servo.angle(pan_servo.angle()pan_output)
#将最终值传入两个舵机中追踪目标tilt_servo.angle(tilt_servo.angle()-tilt_output)#
Servo直接从pyd导入了servo类。
所以可以直接写成Servo()。
2引脚对应关系Servo(1)——P7Servo(2)——P8Servo(3)——P9。
1因此我们可以知道pan_servo.calibration就是对P7进行相应的控制因为pan_servoServo(1)。
2tilt_servo.calibration就是对P8控制因为tilt_servoServo(2)
1pan_servo.calibration(500,2500,500)
这个其实就是设置舵机的脉宽的。
因为我们知道常见的舵机周期都是20ms脉宽都是再500us到2500us之间。
2所以这里的第一个参数是500第二个参数是2500。
第三个参数是舵机0°位置根据下图可以知道也是500。
最后两个值是可以填可不填的个人不建议填写。
pan_servo.angle()是当前舵机角度,pan_output是通过PID计算出来的偏移角度。
1注意因为云台是比较稳定的不要求高反应速度所以我猜测只使用了PI而没有使用PID。
因此我们可以看到pan_pid和tilt_pid只有P和I两个参数。
2I的参数不需要进行调整imax是用于积分限幅的这个也别更改如果你的云台抖动厉害说明P过大了需要调小。
4最佳的P值是你云台有抖动的前一个值。
这个才是P的最优值。
但是我认为P没必要太大因为云台还是比较稳的。
1当OpenMV连接电脑端IDE的时候运行帧率和不连接电脑端IDE是不一样的。
因为我们连接上电脑端IDE的时候OpenMV会向电脑端IDE传输数据所以会导致帧率下降。
2帧率下降会导致我们实际脱机跑的时候PID参数和连接上电脑端IDE时候的PID参数不一样。
3所以我们需要点击电脑端右上角的禁用或者是Disable。
被禁用之后我们的效果就是脱机之后真实运行效果。
isnan(self._last_derivative):derivative
self._last_derivative))self._last_error
https://blog.csdn.net/weixin_52385589/article/details/126334744
sensor.reset()sensor.set_auto_gain(False)sensor.set_pixformat(sensor.GRAYSCALE)
sensor.RGB565sensor.set_framesize(sensor.
o***rs)sensor.skip_frames(time900)
affect.sensor.set_auto_exposure(False,
1000)#在这里调节曝光度调节完可以比较清晰地看清激光点sensor.set_auto_whitebal(False)
off.sensor.set_auto_gain(False)
img.find_blobs(threshold,x_stride1,
pixels_threshold0,mergeFalse,margin1)if
blobs[0]#img.draw_rectangle(b[0:4])
range(len(blobs)-1):#img.draw_rectangle(b[0:4])
blobs[i][6]cycxint(cx/len(blobs))cyint(cy/len(blobs))#img.draw_cross(cx,
2版权归C站博主Huiyeee所有用了代码的同学一定要去Huiyeee的博主下面感谢
FindCR():counts0w_avg0x_avg0y_avg0judge0shape0c_times0r_times0max_size0cx0cy0while(counts30):if(pin1.value()0):breakcountscounts1clock.tick()#返回以毫秒计的通电后的运行时间。
img
sensor.snapshot().lens_corr(strength
1.0)#抓取一帧的图像并返回一个image对象#img.find_blobs()查找图像中所有色块并返回包含每个色块的色块对象列表flag0blobsimg.find_blobs(thresholds,
blobs:max_blobfind_max(blobs)if
img.find_circles(max_blob.rect(),threshold
c.magnitude()5000:c_timesc_times1cxcxc.x()cycyc.y()#img.draw_circle(c.x(),c.y(),c.r(),(0,255,0))if
c_times5:judge1shape1print(circle)cxint(cx/c_times)cyint(cy/c_times)breakfor
img.find_rects(max_blob.rect(),threshold
10):img.draw_rectangle(r.x(),r.y(),r.w(),r.h(),(0,255,0))print(r)if
r_times:judge1shape0print(rect)breakif
abs(max_blob.w()-max_blob.h())4:if
shape1:x_avgcxy_avgcyelse:x_avg(max_blob.x()0.5*max_blob.w()x_avg)max_blob.cx()y_avg(max_blob.y()0.5*max_blob.h()y_avg)max_blob.cy()max_sizemax_size2flag1#if(max_blob.cx()-max_blob.x()w_avg):#w_avgmax_blob.cx()-max_blob.x()#if(max_blob.w()-max_blob.cx()max_blob.x())x_avg:#x_avgmax_blob.w()-max_blob.cx()max_blob.x()#if(max_blob.cy()-max_blob.y()w_avg):#w_avgmax_blob.cy()-max_blob.y()#if(max_blob.w()-max_blob.cy()max_blob.y())x_avg:#x_avgmax_blob.w()-max_blob.cy()max_blob.y()if
max_blob.w()w_avg:w_avgmax_blob.w()if
max_blob.h()w_avg:w_avgmax_blob.h()#amath.sqrt((max_blob.cx()-max_blob.x())**2-(max_blob.cy()-max_blob.y())**2)#if
aw_avg:#w_avgaimg.draw_rectangle(max_blob.rect())#画矩形框
返回一个矩形元组可当作roi区域img.draw_cross(max_blob.cx(),max_blob.cy())if
shape0:img.draw_cross(int(x_avg/max_size),int(y_avg/max_size))#画十字
---返回中心点x和y坐标else:img.draw_cross(x_avg,y_avg)#print(clock.fps())#clock.fps()
shape0:print(int(x_avg/max_size),int(y_avg/max_size),int(w_avg))data[int(x_avg/max_size)1,int(y_avg/max_size)-2
shape1:data[x_avg,y_avg,int(w_avg),shape]return
#初始化设置sensor.set_pixformat(sensor.RGB565)
#设置为彩色sensor.set_framesize(sensor.QVGA)
#跳过前2000ms的图像sensor.set_auto_gain(False)
关闭自动自动增益。
默认开启的。
sensor.set_auto_whitebal(False)
#创建一个clock便于计算FPS看看到底卡不卡judge0r_time0a_r0a_c0a_rt0c_time0rt_time0row_data[-1,-1]while(judge0):
sensor.snapshot().lens_corr(strength
1.0)blobsimg.find_blobs(thresholds,pixels_threshold10,area_threshold10)#openmv自带的寻找色块函数。
#pixels_threshold是像素阈值面积小于这个值的色块就忽略#roi是感兴趣区域只在这个区域内寻找色块#are_threshold是面积阈值如果色块被框起来的面积小于这个值会被过滤掉#print(该形状占空比为,blob.density())if
blobs:max_blobfind_max(blobs)if
max_blob:#print(该形状的面积为,area)#density函数居然可以自动返回色块面积/外接矩形面积这个值太神奇了官方文档还是要多读if
max_blob.density()0.78:#理论上矩形和他的外接矩形应该是完全重合#但是测试时候发现总会有偏差多次试验取的这个值。
下面圆形和三角形亦然r_timer_time1#a_ra_rarea#areaint(max_blob.x()*max_blob.y()*max_blob.density()*0.0185)img.draw_rectangle(max_blob.rect())print(长方形长,max_blob.density())if
r_time1:#areaint(a_r/r_time)#print(area)judge1row_data[0]1print(检测为长方形
max_blob.density()0.46:#areaint(max_blob.x()*max_blob.y()*max_blob.density()*0.0575)c_timec_time1#a_ca_careaimg.draw_circle((max_blob.cx(),
max_blob.cy(),int((max_blob.w()max_blob.h())/4)))print(圆形半径,max_blob.density())if
c_time8:#areaint(a_c/c_time)#print(area)judge1row_data[0]2print(检测为圆
max_blob.density()0.2:#areaint(max_blob.x()*max_blob.y()*max_blob.density()*0.0207)rt_timert_time1#a_rta_rtareaimg.draw_cross(max_blob.cx(),
max_blob.cy())print(max_blob.density(),)if
rt_time20:#areaint(a_rt/rt_time)#if
c_time0:#areaarea-10*c_time#print(area)judge1row_data[0]3print(检测为三角型
#基本上占空比小于0.4的都是干扰或者三角形索性全忽略了。
continue#row_data[1]areaarea0count0while(1):clock.tick()img
sensor.snapshot().lens_corr(strength
1.0)img.binary(thresholds)img.draw_rectangle(80,40,150,120)x_init80y_init40for
img.get_pixel(ix_init,jy_init)[0]255:countcount1break#img.draw_rectangle(80,40,150,120)#staimg.get_statistics(thresholds,
roi(80,40,150,120))#areaarea(30-sta.mean())*1000#countscounts1#print(sta.mean())#if(counts50):#areaint(area/counts*0.0031495)#print(area)#breakrow_data[1]int(count*0.02329*1.14946236559)#\print(row_data[1])databytearray(row_data)uart.write(u_start)uart.write(data)uart.write(u_over)#-------------------------------------------------------------------------#threshold[(90,
img.find_blobs(threshold,x_stride1,
pixels_threshold0,mergeFalse,margin1)if
blobs[0]#img.draw_rectangle(b[0:4])
range(len(blobs)-1):#img.draw_rectangle(b[0:4])
blobs[i][6]cycxint(cx/len(blobs))cyint(cy/len(blobs))#img.draw_cross(cx,
Pin(P2,Pin.IN,Pin.PULL_UP)#extint
time.clock()#定义时钟对象clockwhile(1):while(pin1.value()0):continuerow_data
[-1,-1,-1,-1,-1,-1]sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.QVGA)sensor.skip_frames(time
500)sensor.set_auto_gain(False)
关闭增益色块识别时必须要关sensor.set_auto_whitebal(False)
关闭白平衡LED(1).on()if(pin1.value()0):continueif(pin2.value()0):detect()row_data[0],row_data[1],row_data[2],row_data[3]FindCR()if(pin1.value()0):continueif(pin2.value()0):detect()LED(1).off()LED(2).on()databytearray(row_data)uart.write(u_start)uart.write(data)uart.write(u_over)print(row_data)LED(2).off()if(pin1.value()0):continuesensor.reset()sensor.set_auto_gain(False)sensor.set_pixformat(sensor.GRAYSCALE)
sensor.RGB565sensor.set_framesize(sensor.
o***rs)sensor.skip_frames(time900)
affect.sensor.set_auto_exposure(False,
1000)sensor.set_auto_whitebal(False)
off.sensor.set_auto_gain(False)
关闭增益色块识别时必须要关times0num[-1,-1,-1]add[-1,-1]while(True):if(pin1.value()0):breakif(pin2.value()0):detect()#EXPOSURE_TIME_SCALE
1.01#current_exposure_time_in_microseconds
默认情况下启用自动曝光控制AEC。
调用以下功能可禁用传感器自动曝光控制。
#
另外“exposure_us”参数在AEC被禁用后覆盖自动曝光值。
#sensor.set_auto_exposure(False,
int(current_exposure_time_in_microseconds
EXPOSURE_TIME_SCALE))#roi(int(row_data[0]-0.5*row_data[2]),int(row_data[1]-0.5*row_data[2]),row_data[2],row_data[2])clock.tick()img
sensor.snapshot().lens_corr(strength
1.0)#抓取一帧的图像并返回一个image对象img.draw_circle(data[0],data[1],int(data[2]*0.5))img.draw_cross(data[0],data[1])img
sensor.snapshot().lens_corr(strength
1.0)#抓取一帧的图像并返回一个image对象row_data[4],row_data[5]color_blob(threshold)if
times0:num[times][row_data[4],row_data[5]]else:if
abs(row_data[5]-num[0][1])10:continue
#丢弃数据timestimes1num[0][row_data[4],row_data[5]]#img.draw_cross(row_data[4],row_data[5])databytearray(row_data)uart.write(u_start)uart.write(data)uart.write(u_over)print(row_data)print(pin2.value())
1sensor.set_pixformat设置的图像类型不同。
1我拿官方代码和上面贴出来的那个代码进行了对比发现了一件事情。
他的sensor.set_pixformat是设置成GRAYSCALE图像而我们这里是设置成RGB565图像。
2将图像画质设置成GRAYSCALE好处在于如果只有两个颜色更容易进行分辨而且每个像素所占空间也减少了可以适当的增加分辨率。
但是也有缺点如果是多颜色识别就会出现问题。
3本题只有三种颜色底板白色追踪的绿点被追踪的红点。
因为只需要追踪一个颜色所以各位可以尝试将
sensor.set_pixformat(sensor.RGB565)
sensor.set_pixformat(sensor.GRAYSCALE)
2图像分辨率sensor.set_framesize(sensor.QQVGA)
1官方例程的分辨率是QQVGA像素点是160x120。
而那个博客的分辨率是QVGA像素点是
2更高的分辨率识别效果更好但是分辨率也别无脑调高否则颜色阈值方便会很难设置。
1这个就是给OpenMV初始化一个缓冲时间他那边是设置的跳过900张图片。
官方例程是跳过10个图片。
4sensor.set_auto_exposure(False,
1这个是用于设置曝光度的曝光过度照片看起来会过亮曝光不足图片看起来会太暗。
3C站那位是设置的每1ms曝光一次。
你们可以根据自己测试结果来设置。
5sensor.set_auto_whitebal(False)和sensor.set_auto_gain(False)
1按理来说颜色识别的话这两个都需要关闭的。
C站另外那个博客就是都关闭了。
但是官方只关闭了set_auto_whitebal()白平衡。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback