【光电智造】OpenCV入门学习基础教程(从小白变大神)

今日光电 2024-04-02 18:04

今日光电

     有人说,20世纪是电的世纪,21世纪是光的世纪;知光解电,再小的个体都可以被赋能。追光逐电,光赢未来...欢迎来到今日光电!




----追光逐电 光赢未来----

Opencv是用于快速处理图像处理、计算机视觉问题的工具,支持多种语言进行开发如c++、python、java等,下面这篇文章主要给大家介绍了关于openCV入门学习基础教程的相关资料,需要的朋友可以参考下


一、Canny边缘检测


该边缘检测法步骤如下:


  1. 使用高斯滤波器,以平滑图像,滤除噪声。

  2. 计算图像中每个像素点的梯度强度和方向。

  3. 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。

  4. 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。

  5. 通过抑制孤立的弱边缘最终完成边缘检测。


高斯滤波


我们要进行边缘检测过程中肯定要进行梯度计算,计算梯度时那些噪音点也会影响梯度的变化,因此进行去噪。





梯度和方向


使用sobel算子,进行梯度大小和方向的计算。




非极大值抑制 NMS


算完梯度后,有些可能大点,有些可能小点,在一个核中,把一些小的梯度值抑制掉,只保留大的,即明显的。


如人脸识别,能够把脸框起来(有多个框框到脸了,只保留最好的。)


法1:



蓝线表示方向,dTmp1和dTmp2都是亚像素点,g1g2g3g4都是知道的,可求dTmp1和dTmp2。在c比dTmp1和dTmp2都大的情况下,保留c,否则就被抑制掉了。


法2:




比如我们选择倾斜45°,就过了g1和g4了(上上图),就不用插值了。当前方向离哪个角度近就用选择哪个。


右图中如果A比BC都大,那么A就保存下来了。


双阈值


对一些所有可能边界进行过滤,只保留最真实的。



A点大于maxVal 就是边界 如果有小于minVale的,那就省略掉。


他俩之间的B C分别进行讨论,如果c和边界是连着的,就保留。B没连着,舍弃。


v1=cv2.Canny(img,80,150)


80 150为下上阈值,一定范围内,下阈值越小,上阈值越小越容易被当作边缘。


  1. | img=cv2.imread("./data/gd06.jpg",cv2.IMREAD_GRAYSCALE)

  2. | v1=cv2.Canny(img,80,150)

  3. | v2=cv2.Canny(img,50,100)

  4. | res = np.hstack((v1,v2))

  5. | cv_show('res',res)



  1. | img=cv2.imread("./data/gd05.jpg",cv2.IMREAD_GRAYSCALE)

  2. | v1=cv2.Canny(img,120,250)

  3. | v2=cv2.Canny(img,50,100)

  4. | res = np.hstack((v1,v2))

  5. | cv_show('res',res)



二、 图像轮廓


上面说的是边缘,随便一个线段也能被检测成边缘。而轮廓是一个整体,正常是封闭的连在一起的。


2.1 轮廓收集


cv2.findContours(img,mode,method)


  • RETR_EXTERNAL :只检索最外面的轮廓;

  • RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;

  • RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;

  • RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次;(常用,推荐)


method:轮廓逼近方法


  • CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。

  • CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。




上图就是两种method,一个是整个框,一个是点,都能起到定位作用。


为了更高的准确率,我们选择使用二值图像:


  1. | img = cv2.imread('contours.png')

  2. | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

  3. | ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 127为分割阈值,超过的部分取255

  4. | cv_show('thresh',thresh)


这里用到了cv2.threshold 是上一篇文章学的。




  1. | # contours轮廓信息 hierarchy层级

  2. | contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)


其返回值有两个:


  • 轮廓的信息:比如上面5个图案,10个边缘(内边缘外边缘),这10个边缘信息保存在了contours元组里。

  • 层级:hierarchy 暂时用不上,用到了再说。


2.2 轮廓绘制


res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)


参数为:图像,轮廓,轮廓索引(-1默认所有),颜色模式(BGR),线条厚度(不宜太大)


  1. | img = cv2.imread('contours.png')

  2. | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

  3. | ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 127为分割阈值,超过的部分取255

  4. |

  5. | # contours轮廓信息 hierarchy层级

  6. | contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

  7. |

  8. | #传入 图像,轮廓,轮廓索引(-1默认所有),颜色模式(BGR),线条厚度(不宜太大)

  9. | # 注意需要copy,不然原图会变。。。

  10. | draw_img = img.copy()

  11. | res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)

  12. | cv_show('res',res)




仔细看它把10个(内外)轮廓都画出来了,这与我们传入的参数 -1 有关。


当然我们也可以选择其中某个:


  1. | draw_img = img.copy()

  2. | # 三角的外轮廓

  3. | res = cv2.drawContours(draw_img, contours, 0, (0, 0, 255), 2)

  4. | cv_show('res',res)


  1. | draw_img = img.copy()

  2. | # 三角的内轮廓

  3. | res = cv2.drawContours(draw_img, contours, 1, (0, 0, 255), 2)

  4. | cv_show('res',res)


  1. | draw_img = img.copy()

  2. | # 六边形外轮廓

  3. | res = cv2.drawContours(draw_img, contours, 2, (0, 0, 255), 2)

  4. | cv_show('res',res)


2.3 轮廓特征


这里就介绍个周长和面积吧,后面用到别的再说。


  1. | cnt = contours[0] # 第0个轮廓 三角的外轮廓

  2. | #周长,True表示轮廓是闭合的

  3. | cv2.arcLength(cnt,True) # 8500.5

  4. | #面积

  5. | cv2.contourArea(cnt) # 437.9482651948929


2.4 轮廓近似


什么是轮廓近似呢,比如下图左侧图案很麻烦,我们可以把它近似看成右边的,就是轮廓近似。




这个的原理其实也很简单,我发挥我的绘画功能给你们展示一下:



把曲线AB近似成直线AB,至于要d


我们近似一下下图:



边缘绘制:


  1. | img = cv2.imread('contours2.png')

  2. | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

  3. | ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

  4. |

  5. | contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

  6. | cnt = contours[0]

  7. |

  8. | draw_img = img.copy()

  9. | res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)

  10. | cv_show('res',res)



  1. | epsilon = 0.02*cv2.arcLength(cnt,True) # 周长百分比 0.02

  2. |

  3. | # 参数:轮廓 阈值,一般用周长百分比

  4. | # 返回:轮廓

  5. | approx = cv2.approxPolyDP(cnt,epsilon,True)

  6. |

  7. | draw_img = img.copy()

  8. | res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)

  9. | cv_show('res',res)


approx = cv2.approxPolyDP(cnt,epsilon,True)


  • 参数:轮廓 阈值,一般用周长百分比

  • 返回:轮廓



把阈值变大一点:


  1. | epsilon = 0.1*cv2.arcLength(cnt,True)

  2. | approx = cv2.approxPolyDP(cnt,epsilon,True)

  3. |

  4. | draw_img = img.copy()

  5. | res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)

  6. | cv_show('res',res)



2.5 外接图形


  1. | img = cv2.imread('contours.png')

  2. |

  3. | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

  4. | ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

  5. | # binary,

  6. | contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

  7. | cnt = contours[0]

  8. |

  9. | # 外接矩形 得到x,y,w,h就能把矩形画出来了

  10. | x,y,w,h = cv2.boundingRect(cnt)

  11. | img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

  12. | cv_show('img',img)


x,y,w,h = cv2.boundingRect(cnt)



三、图像金字塔


3.1 高斯金字塔



高斯金字塔:向下采样(缩小)




上面金字塔最底层44 往上一层变成22 长宽变为原来一半面积变为原来1/4,去除所有偶数行和列就是为了这一操作。


高斯金字塔:向上采样(扩大)




用0填充后,用卷积核把那几个值分布在0上,获得近似值。


  1. | img=cv2.imread("./data/gd01.jpg")

  2. | cv_show('img',img)

  3. |

  4. | up=cv2.pyrUp(img)

  5. | cv_show('up',up)

  6. |

  7. | up2=cv2.pyrUp(up)

  8. | cv_show('up2',up2)

  9. |

  10. | down=cv2.pyrDown(img)

  11. | cv_show('down',down)


上面其实就是图片的放大与缩小。


下面要注意,缩小放大后的图片会变得模糊,毕竟之前我们是用0填充,卷积核计算获得的近似值。


  1. | # 先扩大后缩小后,由于当时是用0填充的,会损失信息。

  2. | up=cv2.pyrUp(img)

  3. | up_down=cv2.pyrDown(up)

  4. | # 显然变得模糊了

  5. | cv_show('up_down',np.hstack((img,up_down)))




明显右边模糊了,我们把两张图片做个差值:


  1. | # 做差就能看出区别

  2. | up=cv2.pyrUp(img)

  3. | up_down=cv2.pyrDown(up)

  4. | cv_show('img-up_down',img-up_down)




这就是不同的部分。


3.2 拉普拉斯金字塔


和上面最后缩小放大后的图片一样,拉普拉斯这个每一层都是 原始-缩小(放大了的图片) 第二层用第一层的结果去减了。


  1. | down=cv2.pyrDown(img)

  2. | down_up=cv2.pyrUp(down)

  3. | l_1=img-down_up

  4. | cv_show('l_1',l_1)



四、直方图


4.1 像素直方图绘制




左侧灰度图像素点 右侧像素点直方图


cv2.calcHist(images,channels,mask,histSize,ranges)


  • images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]

  • channels: 同样用中括号括来它会告函数我们统幅图像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩+ 色图像 的传入的参数可以是 [0][1][2] 它们分别对应着 BGR。

  • mask: 掩模图像。统计整幅图像的直方图就mask = None。但是如果你想统计图像某一分的直方图的你就制作一个掩模图像并使用它。

  • histSize:BIN 的数目。也应用中括号括来如0-10是一个柱子 11-20是一个柱

  • ranges: 像素值范围常为 [0256]


  1. | img = cv2.imread('./data/gd01.jpg',0) #0表示灰度图

  2. | hist = cv2.calcHist([img],[0],None,[256],[0,256])

  3. | plt.hist(img.ravel(),256);

  4. | plt.show()




  1. | img = cv2.imread('./data/gd01.jpg')

  2. | color = ('b','g','r')

  3. | for i,col in enumerate(color):

  4. ||histr = cv2.calcHist([img],[i],None,[256],[0,256])

  5. | plt.plot(histr,color = col)

  6. | plt.xlim([0,256])


mask操作


我们取一小块区域,然后获得图片中这一块区域的图像


  1. | # 创建mast

  2. | mask = np.zeros(img.shape[:2], np.uint8)

  3. | print (mask.shape)

  4. | mask[100:300, 100:400] = 255

  5. | cv_show('mask',mask)



  1. | masked_img = cv2.bitwise_and(img, img, mask=mask)#与操作

  2. | cv_show('masked_img',masked_img)



  1. | hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])

  2. | hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])

  3. | plt.subplot(221), plt.imshow(img, 'gray')

  4. | plt.subplot(222), plt.imshow(mask, 'gray')

  5. | plt.subplot(223), plt.imshow(masked_img, 'gray')

  6. | plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)

  7. | plt.xlim([0, 256])

  8. | plt.show()



4.2 直方图均衡化



如上图,像素点都集中在一个地方,我们在不破坏其特征的前提下让高瘦的分布变得矮胖一点,亮度什么的也就都会发生些变化。




注:这里的映射是 累积概率*取值范围(255-0)


  1. | img = cv2.imread('./data/gd01.jpg',0) #0表示灰度图 #clahe

  2. | plt.hist(img.ravel(),256);

  3. | plt.show()




  1. | equ = cv2.equalizeHist(img)

  2. | plt.hist(equ.ravel(),256)

  3. | plt.show()




  1. | res = np.hstack((img,equ))

  2. | cv_show('res',res)




图片比之前亮一些了。


4.3 自适应直方图均衡化


  1. | clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))

  2. | res_clahe = clahe.apply(img)

  3. | res = np.hstack((img,equ,res_clahe))

  4. | cv_show('res',res)



五、傅里叶变换


我们生活在时间的世界中,早上7:00起来吃早饭,8:00去挤地铁,9:00开始上班...


以时间为参照就是时域分析,但是在频域中一切都是静止的!


傅里叶变换的作用


  • 高频:变化剧烈的灰度分量,例如边界

  • 低频:变化缓慢的灰度分量,例如一片大海


滤波


  • 低通滤波器:只保留低频,会使得图像模糊

  • 高通滤波器:只保留高频,会使得图像细节增强


opencv中主要就是cv2.dft()和cv2.idft(),输入图像需要先转换成np.float32 格式


得到的结果中频率为0的部分会在左上角,通常要转换到中心位置,通过shift变换。


cv2.dft()返回的结果是双通的(实部,虚部),通常还需要转换成图像格式才能展示(0,255)。


  1. | import numpy as np

  2. | import cv2

  3. | from matplotlib import pyplot as plt

  4. | img = cv2.imread('./data/gd06.jpg',0)

  5. | img_float32 = np.float32(img)

  6. | dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)

  7. | dft_shift = np.fft.fftshift(dft)

  8. | magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))

  9. | plt.subplot(121),plt.imshow(img, cmap = 'gray')

  10. | plt.title('Input Image'), plt.xticks([]), plt.yticks([])

  11. | plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')

  12. | plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])

  13. | plt.show()



  1. | img = cv2.imread('./data/gd06.jpg',0)

  2. | img_float32 = np.float32(img)

  3. | dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)

  4. | dft_shift = np.fft.fftshift(dft)

  5. | rows, cols = img.shape

  6. | crow, ccol = int(rows/2) , int(cols/2) # 中心位置

  7. | # 低通滤波

  8. | mask = np.zeros((rows, cols, 2), np.uint8)

  9. | mask[crow-30:crow+30, ccol-30:ccol+30] = 1

  10. | # IDFT

  11. | fshift = dft_shift*mask

  12. | f_ishift = np.fft.ifftshift(fshift)

  13. | img_back = cv2.idft(f_ishift)

  14. | img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])

  15. | plt.subplot(121),plt.imshow(img, cmap = 'gray')

  16. | plt.title('Input Image'), plt.xticks([]), plt.yticks([])

  17. | plt.subplot(122),plt.imshow(img_back, cmap = 'gray')

  18. | plt.title('Result'), plt.xticks([]), plt.yticks([])

  19. | plt.show()



  1. | img = cv2.imread('./data/gd06.jpg',0)

  2. | img_float32 = np.float32(img)

  3. | dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)

  4. | dft_shift = np.fft.fftshift(dft)

  5. | rows, cols = img.shape

  6. | crow, ccol = int(rows/2) , int(cols/2) # 中心位置

  7. | # 高通滤波

  8. | mask = np.ones((rows, cols, 2), np.uint8)

  9. | mask[crow-30:crow+30, ccol-30:ccol+30] = 0

  10. | # IDFT

  11. | fshift = dft_shift*mask

  12. | f_ishift = np.fft.ifftshift(fshift)

  13. | img_back = cv2.idft(f_ishift)

  14. | img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])

  15. | plt.subplot(121),plt.imshow(img, cmap = 'gray')

  16. | plt.title('Input Image'), plt.xticks([]), plt.yticks([])

  17. | plt.subplot(122),plt.imshow(img_back, cmap = 'gray')

  18. | plt.title('Result'), plt.xticks([]), plt.yticks([])

  19. | plt.show()



六、模板匹配


模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv里有6种,然后将每次计算的结果放入一个矩阵里,作为结果输出。


假如原图形是AxB大小,而模板是axb大小,则输出结果的矩阵是(A-a+1)x(B-b+1)


  1. | img = cv2.imread('./data/gd04.jpg', 0)

  2. | template = cv2.imread('./data/gd_face.jpg', 0)

  3. | h, w = template.shape[:2]




它们的关系就是(A-a+1)x(B-b+1)


res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)


  • TM_SQDIFF:计算平方不同,计算出来的值越小,越相关

  • TM_CCORR:计算相关性,计算出来的值越大,越相关

  • TM_CCOEFF:计算相关系数,计算出来的值越大,越相关

  • TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关

  • TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关

  • TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关


  1. | methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',

  2. | 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']

  3. | res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)

  4. | # res.shape 为(139, 458)

  5. | # 最小值最大值及其坐标位置 因为用的cv2.TM_SQDIFF 所以越小越好

  6. | min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)



比如我要用到的图像和脸:





  1. | for meth in methods:

  2. | img2 = img.copy()

  3. | # 匹配方法的真值

  4. | method = eval(meth)

  5. | print (method)

  6. | res = cv2.matchTemplate(img, template, method)

  7. | min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

  8. | # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED,取最小值

  9. | if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:

  10. | top_left = min_loc

  11. | else:

  12. | top_left = max_loc

  13. | bottom_right = (top_left[0] + w, top_left[1] + h)

  14. | # 画矩形

  15. | cv2.rectangle(img2, top_left, bottom_right, 255, 2)

  16. | plt.subplot(121), plt.imshow(res, cmap='gray')

  17. | plt.xticks([]), plt.yticks([]) # 隐藏坐标轴

  18. | plt.subplot(122), plt.imshow(img2, cmap='gray')

  19. | plt.xticks([]), plt.yticks([])

  20. | plt.suptitle(meth)

  21. | plt.show()



匹配多个对象


能匹配一个当然也能匹配多个:


  1. | img_rgb = cv2.imread('./data/mario.jpg')

  2. | img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

  3. | template = cv2.imread('./data/mario_coin.jpg', 0)

  4. | h, w = template.shape[:2]

  5. | res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)

  6. | threshold = 0.8

  7. | # 取匹配程度大于%80的坐标

  8. | loc = np.where(res >= threshold)

  9. | for pt in zip(*loc[::-1]): # *号表示可选参数

  10. | bottom_right = (pt[0] + w, pt[1] + h)

  11. | cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)

  12. | cv2.imshow('img_rgb', img_rgb)

  13. | cv2.waitKey(0)



匹配金币:



来源:新机器视觉



申明:感谢原创作者的辛勤付出。本号转载的文章均会在文中注明,若遇到版权问题请联系我们处理。


 

----与智者为伍 为创新赋能----


【说明】欢迎企业和个人洽谈合作,投稿发文。欢迎联系我们
诚招运营合伙人 ,对新媒体感兴趣,对光电产业和行业感兴趣。非常有意者通过以下方式联我们!条件待遇面谈
投稿丨合作丨咨询

联系邮箱:uestcwxd@126.com

QQ:493826566


评论
  • 图森未来的“夺权之争”拉扯了这么久,是该画上句号了。大约9年前,侯晓迪、陈默、郝佳男等人共同创立了图森未来,初衷是以L4级别的无人驾驶卡车技术为全球物流运输行业赋能。此后,先后获得了5轮融资,累计融资额超过6.5亿美元,并于2021年成功在美国纳斯达克上市,成为全球自动驾驶第一股。好景不长,2023年市场屡屡传出图森未来裁员、退市的消息。今年1月份,图森未来正式宣布退市,成为了全球首个主动退市的自动驾驶公司。上市匆匆退市也匆匆,其背后深层原因在于高层的频繁变动以及企业的转型调整。最近,图森未来的
    刘旷 2024-12-27 10:23 66浏览
  • 在当今这个科技飞速发展的时代,物联网(IoT)已经不再是一个陌生的概念,它正以一种前所未有的速度改变着我们的生活和工作方式,像一股无形的力量,将世界紧密地连接在一起,引领我们步入一个全新的智能时代。物联网是什么简单来说,物联网就是通过感知设备、网络传输、数据处理等技术手段,实现物与物、人与物之间的互联互通和智能化管理。想象一下,你的家里所有的电器都能 “听懂” 你的指令,根据你的习惯自动调节;工厂里的设备能够实时监测自身状态,提前预警故障;城市的交通系统可以根据实时路况自动优化信号灯,减少拥堵…
    Jeffreyzhang123 2024-12-27 17:18 76浏览
  • 引言工程师作为推动科技进步和社会发展的核心力量,在各个领域发挥着关键作用。为深入了解工程师的职场现状,本次调研涵盖了不同行业、不同经验水平的工程师群体,通过问卷调查、访谈等方式,收集了大量一手数据,旨在全面呈现工程师的职场生态。1. 工程师群体基本信息行业分布:调研结果显示,工程师群体广泛分布于多个行业,其中制造业占比最高,达到 90%,其次是信息技术、电子通信、能源等行业。不同行业的工程师在工作内容、技术要求和职业发展路径上存在一定差异。年龄与经验:工程师群体以中青年为主,30 - 45 岁年
    Jeffreyzhang123 2024-12-27 17:39 98浏览
  • 在科技飞速发展的今天,医疗电子作为一个融合了医学与电子技术的交叉领域,正以前所未有的速度改变着我们的医疗模式和健康生活。它宛如一颗璀璨的明珠,在医疗领域绽放出耀眼的光芒,为人类的健康福祉带来了诸多惊喜与变革。医疗电子的神奇应用医疗电子的应用范围极为广泛,深入到医疗的各个环节。在诊断方面,各种先进的医学成像设备堪称医生的 “火眼金睛”。X 光、CT、MRI 等成像技术,能够清晰地呈现人体内部的结构和病变情况,帮助医生准确地发现疾病。以 CT 为例,它通过对人体进行断层扫描,能够提供比传统 X 光更
    Jeffreyzhang123 2024-12-27 15:46 92浏览
  • 采购与分销是企业运营中至关重要的环节,直接影响到企业的成本控制、客户满意度和市场竞争力。以下从多个方面介绍如何优化采购与分销:采购环节优化供应商管理供应商评估与选择:建立一套全面、科学的供应商评估体系,除了考虑价格因素,还要综合评估供应商的产品质量、交货期、信誉、研发能力、售后服务等。通过多维度评估,选择那些能够提供优质产品和服务,且与企业战略目标相契合的供应商。建立长期合作关系:与优质供应商建立长期稳定的合作关系,这种合作模式可以带来诸多好处。双方可以在信任的基础上进行深度沟通与协作,共同开展
    Jeffreyzhang123 2024-12-27 17:43 91浏览
  • 一、前言 回首2024,对于我而言,是充满挑战与收获的一年。在这一年里,我积极参与了论坛的众多活动,不仅拓宽了我的认知边界(有些东西不是你做不到,而是你想不到),还让我在实践中收获了宝贵的经验和。同时,多种多样的论坛活动让我们全方面的接受新东西,连接新知识,多种类型的的活动交织了你我的2024。在这里说一说对过去一年的活动经历,进行一次年终总结,并谈谈我的收获和感受,以及对2025年的展望。二、活动足迹(一)快速体验:机智云Gokit2.0开发板初体验 机智云Gokit2.0开发板的体验活动让大
    无言的朝圣 2024-12-27 14:50 68浏览
  •       在科技日新月异的今天,智能手机已不再仅仅是通讯工具,它更成为了我们娱乐、学习、工作的核心设备。特别是在游戏体验方面,用户对于手机的性能要求愈发严苛,追求极致流畅与沉浸感。正是基于这样的市场需求,一加品牌于2024年12月26日正式推出了其最新的游戏性能旗舰——一加 Ace 5系列,包括一加 Ace 5与一加 Ace 5 Pro两款力作。这一系列深度聚焦于性能与游戏体验,旨在为用户带来前所未有的游戏盛宴。骁龙8系旗舰平台,性能跃升新高度
    科技财经汇 2024-12-26 22:31 75浏览
  • 在科技飞速发展的今天,汽车不再仅仅是一种交通工具,更是一个融合了先进技术的移动智能空间。汽车电子作为汽车产业与电子技术深度融合的产物,正以前所未有的速度推动着汽车行业的变革,为我们带来更加智能、安全、舒适的出行体验。汽车电子的发展历程汽车电子的发展可以追溯到上世纪中叶。早期,汽车电子主要应用于发动机点火系统和简单的电子仪表,功能相对单一。随着半导体技术的不断进步,集成电路被广泛应用于汽车领域,使得汽车电子系统的性能得到了显著提升。从电子燃油喷射系统到防抱死制动系统(ABS),从安全气囊到车载导航
    Jeffreyzhang123 2024-12-27 11:53 104浏览
  • 在当今这个数字化的时代,电子设备无处不在,从我们手中的智能手机、随身携带的笔记本电脑,到复杂的工业控制系统、先进的医疗设备,它们的正常运行都离不开一个关键的 “幕后英雄”—— 印刷电路板(Printed Circuit Board,简称 PCB)。PCB 作为电子设备中不可或缺的重要部件,默默地承载着电子元件之间的连接与信号传输,是整个电子世界的基石。揭开 PCB 的神秘面纱PCB,简单来说,就是一块由绝缘材料制成的板子,上面通过印刷、蚀刻等工艺形成了导电线路和焊盘,用于固定和连接各种电子元件。
    Jeffreyzhang123 2024-12-27 17:21 81浏览
  • 起源与基础20 世纪 60 年代:可编程逻辑设备(PLD)的概念出现,一种被称为 “重构能力” 的芯片的可编程性吸引了许多工程师和学者。20 世纪 70 年代:最早的可编程逻辑器件 PLD 诞生,其输出结构是可编程的逻辑宏单元,它的硬件结构设计可由软件完成,设计比纯硬件的数字电路更灵活,但结构简单,只能实现小规模电路。诞生与发展20 世纪 80 年代中期:为弥补 PLD 只能设计小规模电路的缺陷,复杂可编程逻辑器件 CPLD 被推出,它具有更复杂的结构,能够实现较大规模的电路设计。1988 年:
    Jeffreyzhang123 2024-12-27 10:41 72浏览
  • 一、引言无人机,作为近年来迅速崛起的新兴技术产物,正以前所未有的速度改变着众多行业的运作模式,从民用领域的航拍、物流,到工业领域的测绘、巡检,再到军事领域的侦察、打击等,无人机的身影无处不在。为了深入了解无人机的现状,本次调研综合了市场数据、行业报告、用户反馈等多方面信息,全面剖析无人机的发展态势。二、市场规模与增长趋势随着技术的不断进步和成本的逐渐降低,无人机市场呈现出爆发式增长。近年来,全球无人机市场规模持续扩大,预计在未来几年内仍将保持较高的增长率。从应用领域来看,消费级无人机市场依然占据
    Jeffreyzhang123 2024-12-27 17:29 125浏览
  • 发明阶段(20世纪80年代至90年代)起源:当时ASIC设计成本高,周期长,流片失败率高,业界需要一种通用的半导体器件进行流片前测试和验证,可编程逻辑器件就此产生。诞生:1980年,Xilinx公司成立。1985年,Ross Freeman制造了第一片PFGA芯片XC2064,采用4输入,1输出的LUT和FF结合的基本逻辑单元。发展阶段(1992年至1999年)容量提升:FPGA容量不断上涨,芯片面积逐渐增大,为架构穿心提供空间,复杂功能可以实现。布线问题凸显:缩着芯片复杂度增加,片上资源的互连
    Jeffreyzhang123 2024-12-27 10:26 88浏览
  • 在当今科技飞速发展的时代,工业电子作为现代制造业的中流砥柱,正以前所未有的速度推动着各个行业的变革与进步。从汽车制造到航空航天,从智能家居到工业自动化,工业电子的身影无处不在,为我们的生活和生产带来了巨大的改变。工业电子的崛起与发展工业电子的发展历程可谓是一部波澜壮阔的科技进化史。追溯到上世纪中叶,电子技术开始逐渐应用于工业领域,最初主要是简单的电子控制装置,用于提高生产过程的自动化程度。随着半导体技术、计算机技术和通信技术的不断突破,工业电子迎来了爆发式的增长。集成电路的发明使得电子设备的体积
    Jeffreyzhang123 2024-12-27 15:40 101浏览
  • 在当今竞争激烈的商业世界中,供应链管理已成为企业生存与发展的核心竞争力之一。它就像一条无形的纽带,将供应商、制造商、分销商、零售商直至最终消费者紧密相连,确保产品和服务能够高效、顺畅地流转。今天,就让我们一同深入探索供应链管理的奥秘。供应链管理是什么简单来说,供应链管理是对从原材料采购、生产制造、产品配送直至销售给最终用户这一整个过程中,涉及的物流、信息流和资金流进行计划、协调、控制和优化的管理活动。它不仅仅是对各个环节的简单串联,更是一种通过整合资源、优化流程,实现整体效益最大化的管理理念和方
    Jeffreyzhang123 2024-12-27 17:27 91浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦